@nextclaw/server 0.4.11 → 0.4.12
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/dist/index.d.ts +41 -1
- package/dist/index.js +182 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -53,6 +53,38 @@ type SessionConfigView = {
|
|
|
53
53
|
maxPingPongTurns?: number;
|
|
54
54
|
};
|
|
55
55
|
};
|
|
56
|
+
type SessionEntryView = {
|
|
57
|
+
key: string;
|
|
58
|
+
createdAt: string;
|
|
59
|
+
updatedAt: string;
|
|
60
|
+
label?: string;
|
|
61
|
+
preferredModel?: string;
|
|
62
|
+
messageCount: number;
|
|
63
|
+
lastRole?: string;
|
|
64
|
+
lastTimestamp?: string;
|
|
65
|
+
};
|
|
66
|
+
type SessionsListView = {
|
|
67
|
+
sessions: SessionEntryView[];
|
|
68
|
+
total: number;
|
|
69
|
+
};
|
|
70
|
+
type SessionMessageView = {
|
|
71
|
+
role: string;
|
|
72
|
+
content: string;
|
|
73
|
+
timestamp: string;
|
|
74
|
+
name?: string;
|
|
75
|
+
tool_call_id?: string;
|
|
76
|
+
};
|
|
77
|
+
type SessionHistoryView = {
|
|
78
|
+
key: string;
|
|
79
|
+
totalMessages: number;
|
|
80
|
+
metadata: Record<string, unknown>;
|
|
81
|
+
messages: SessionMessageView[];
|
|
82
|
+
};
|
|
83
|
+
type SessionPatchUpdate = {
|
|
84
|
+
label?: string | null;
|
|
85
|
+
preferredModel?: string | null;
|
|
86
|
+
clearHistory?: boolean;
|
|
87
|
+
};
|
|
56
88
|
type RuntimeConfigUpdate = {
|
|
57
89
|
agents?: {
|
|
58
90
|
defaults?: {
|
|
@@ -239,6 +271,14 @@ declare function loadConfigOrDefault(configPath: string): Config;
|
|
|
239
271
|
declare function updateModel(configPath: string, model: string): ConfigView;
|
|
240
272
|
declare function updateProvider(configPath: string, providerName: string, patch: ProviderConfigUpdate): ProviderConfigView | null;
|
|
241
273
|
declare function updateChannel(configPath: string, channelName: string, patch: Record<string, unknown>): Record<string, unknown> | null;
|
|
274
|
+
declare function listSessions(configPath: string, query?: {
|
|
275
|
+
q?: string;
|
|
276
|
+
limit?: number;
|
|
277
|
+
activeMinutes?: number;
|
|
278
|
+
}): SessionsListView;
|
|
279
|
+
declare function getSessionHistory(configPath: string, key: string, limit?: number): SessionHistoryView | null;
|
|
280
|
+
declare function patchSession(configPath: string, key: string, patch: SessionPatchUpdate): SessionHistoryView | null;
|
|
281
|
+
declare function deleteSession(configPath: string, key: string): boolean;
|
|
242
282
|
declare function updateRuntime(configPath: string, patch: RuntimeConfigUpdate): Pick<ConfigView, "agents" | "bindings" | "session">;
|
|
243
283
|
|
|
244
|
-
export { type AgentBindingView, type AgentProfileView, type ApiError, type ApiResponse, type BindingPeerView, type ChannelSpecView, type ConfigActionExecuteRequest, type ConfigActionExecuteResult, type ConfigActionManifest, type ConfigActionType, type ConfigMetaView, type ConfigSchemaResponse, type ConfigUiHint, type ConfigUiHints, type ConfigView, type ProviderConfigUpdate, type ProviderConfigView, type ProviderSpecView, type RuntimeConfigUpdate, type SessionConfigView, type UiServerEvent, type UiServerHandle, type UiServerOptions, buildConfigMeta, buildConfigSchemaView, buildConfigView, createUiRouter, executeConfigAction, loadConfigOrDefault, startUiServer, updateChannel, updateModel, updateProvider, updateRuntime };
|
|
284
|
+
export { type AgentBindingView, type AgentProfileView, type ApiError, type ApiResponse, type BindingPeerView, type ChannelSpecView, type ConfigActionExecuteRequest, type ConfigActionExecuteResult, type ConfigActionManifest, type ConfigActionType, type ConfigMetaView, type ConfigSchemaResponse, type ConfigUiHint, type ConfigUiHints, type ConfigView, type ProviderConfigUpdate, type ProviderConfigView, type ProviderSpecView, type RuntimeConfigUpdate, type SessionConfigView, type SessionEntryView, type SessionHistoryView, type SessionMessageView, type SessionPatchUpdate, type SessionsListView, type UiServerEvent, type UiServerHandle, type UiServerOptions, buildConfigMeta, buildConfigSchemaView, buildConfigView, createUiRouter, deleteSession, executeConfigAction, getSessionHistory, listSessions, loadConfigOrDefault, patchSession, startUiServer, updateChannel, updateModel, updateProvider, updateRuntime };
|
package/dist/index.js
CHANGED
|
@@ -20,7 +20,9 @@ import {
|
|
|
20
20
|
buildConfigSchema,
|
|
21
21
|
findProviderByName,
|
|
22
22
|
getPackageVersion,
|
|
23
|
-
isSensitiveConfigPath
|
|
23
|
+
isSensitiveConfigPath,
|
|
24
|
+
SessionManager,
|
|
25
|
+
getWorkspacePathFromConfig
|
|
24
26
|
} from "@nextclaw/core";
|
|
25
27
|
var MASK_MIN_LENGTH = 8;
|
|
26
28
|
var EXTRA_SENSITIVE_PATH_PATTERNS = [/authorization/i, /cookie/i, /session/i, /bearer/i];
|
|
@@ -391,6 +393,137 @@ function updateChannel(configPath, channelName, patch) {
|
|
|
391
393
|
uiHints
|
|
392
394
|
);
|
|
393
395
|
}
|
|
396
|
+
function normalizeSessionKey(value) {
|
|
397
|
+
return value.trim();
|
|
398
|
+
}
|
|
399
|
+
function createSessionManager(config) {
|
|
400
|
+
return new SessionManager(getWorkspacePathFromConfig(config));
|
|
401
|
+
}
|
|
402
|
+
function listSessions(configPath, query) {
|
|
403
|
+
const config = loadConfigOrDefault(configPath);
|
|
404
|
+
const sessionManager = createSessionManager(config);
|
|
405
|
+
const now = Date.now();
|
|
406
|
+
const activeMinutes = typeof query?.activeMinutes === "number" ? Math.max(0, Math.trunc(query.activeMinutes)) : 0;
|
|
407
|
+
const q = (query?.q ?? "").trim().toLowerCase();
|
|
408
|
+
const limit = typeof query?.limit === "number" ? Math.max(0, Math.trunc(query.limit)) : 0;
|
|
409
|
+
const entries = sessionManager.listSessions().map((item) => {
|
|
410
|
+
const key = typeof item.key === "string" ? normalizeSessionKey(item.key) : "";
|
|
411
|
+
if (!key) {
|
|
412
|
+
return null;
|
|
413
|
+
}
|
|
414
|
+
const session = sessionManager.getIfExists(key);
|
|
415
|
+
const messages = session?.messages ?? [];
|
|
416
|
+
const lastMessage = messages.length > 0 ? messages[messages.length - 1] : null;
|
|
417
|
+
const metadata = item.metadata && typeof item.metadata === "object" ? item.metadata : {};
|
|
418
|
+
const label = typeof metadata.label === "string" ? metadata.label.trim() : "";
|
|
419
|
+
const preferredModel = typeof metadata.preferred_model === "string" ? metadata.preferred_model.trim() : "";
|
|
420
|
+
const createdAt = typeof item.created_at === "string" ? item.created_at : (/* @__PURE__ */ new Date(0)).toISOString();
|
|
421
|
+
const updatedAt = typeof item.updated_at === "string" ? item.updated_at : createdAt;
|
|
422
|
+
return {
|
|
423
|
+
key,
|
|
424
|
+
createdAt,
|
|
425
|
+
updatedAt,
|
|
426
|
+
label: label || void 0,
|
|
427
|
+
preferredModel: preferredModel || void 0,
|
|
428
|
+
messageCount: messages.length,
|
|
429
|
+
lastRole: typeof lastMessage?.role === "string" ? lastMessage.role : void 0,
|
|
430
|
+
lastTimestamp: typeof lastMessage?.timestamp === "string" ? lastMessage.timestamp : void 0
|
|
431
|
+
};
|
|
432
|
+
}).filter((item) => Boolean(item));
|
|
433
|
+
const filtered = entries.filter((entry) => {
|
|
434
|
+
if (activeMinutes > 0) {
|
|
435
|
+
const ageMs = now - new Date(entry.updatedAt).getTime();
|
|
436
|
+
if (!Number.isFinite(ageMs) || ageMs > activeMinutes * 6e4) {
|
|
437
|
+
return false;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
if (!q) {
|
|
441
|
+
return true;
|
|
442
|
+
}
|
|
443
|
+
return entry.key.toLowerCase().includes(q) || (entry.label ?? "").toLowerCase().includes(q);
|
|
444
|
+
});
|
|
445
|
+
filtered.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
|
|
446
|
+
const total = filtered.length;
|
|
447
|
+
const sessions = limit > 0 ? filtered.slice(0, limit) : filtered;
|
|
448
|
+
return { sessions, total };
|
|
449
|
+
}
|
|
450
|
+
function getSessionHistory(configPath, key, limit) {
|
|
451
|
+
const normalizedKey = normalizeSessionKey(key);
|
|
452
|
+
if (!normalizedKey) {
|
|
453
|
+
return null;
|
|
454
|
+
}
|
|
455
|
+
const config = loadConfigOrDefault(configPath);
|
|
456
|
+
const sessionManager = createSessionManager(config);
|
|
457
|
+
const session = sessionManager.getIfExists(normalizedKey);
|
|
458
|
+
if (!session) {
|
|
459
|
+
return null;
|
|
460
|
+
}
|
|
461
|
+
const safeLimit = typeof limit === "number" ? Math.min(500, Math.max(1, Math.trunc(limit))) : 200;
|
|
462
|
+
const allMessages = session.messages;
|
|
463
|
+
const messages = allMessages.length > safeLimit ? allMessages.slice(-safeLimit) : allMessages;
|
|
464
|
+
return {
|
|
465
|
+
key: normalizedKey,
|
|
466
|
+
totalMessages: allMessages.length,
|
|
467
|
+
metadata: session.metadata,
|
|
468
|
+
messages: messages.map((message) => {
|
|
469
|
+
const entry = {
|
|
470
|
+
role: message.role,
|
|
471
|
+
content: message.content,
|
|
472
|
+
timestamp: message.timestamp
|
|
473
|
+
};
|
|
474
|
+
if (typeof message.name === "string") {
|
|
475
|
+
entry.name = message.name;
|
|
476
|
+
}
|
|
477
|
+
if (typeof message.tool_call_id === "string") {
|
|
478
|
+
entry.tool_call_id = message.tool_call_id;
|
|
479
|
+
}
|
|
480
|
+
return entry;
|
|
481
|
+
})
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
function patchSession(configPath, key, patch) {
|
|
485
|
+
const normalizedKey = normalizeSessionKey(key);
|
|
486
|
+
if (!normalizedKey) {
|
|
487
|
+
return null;
|
|
488
|
+
}
|
|
489
|
+
const config = loadConfigOrDefault(configPath);
|
|
490
|
+
const sessionManager = createSessionManager(config);
|
|
491
|
+
const session = sessionManager.getIfExists(normalizedKey);
|
|
492
|
+
if (!session) {
|
|
493
|
+
return null;
|
|
494
|
+
}
|
|
495
|
+
if (patch.clearHistory) {
|
|
496
|
+
sessionManager.clear(session);
|
|
497
|
+
}
|
|
498
|
+
if (Object.prototype.hasOwnProperty.call(patch, "label")) {
|
|
499
|
+
const label = typeof patch.label === "string" ? patch.label.trim() : "";
|
|
500
|
+
if (label) {
|
|
501
|
+
session.metadata.label = label;
|
|
502
|
+
} else {
|
|
503
|
+
delete session.metadata.label;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
if (Object.prototype.hasOwnProperty.call(patch, "preferredModel")) {
|
|
507
|
+
const preferredModel = typeof patch.preferredModel === "string" ? patch.preferredModel.trim() : "";
|
|
508
|
+
if (preferredModel) {
|
|
509
|
+
session.metadata.preferred_model = preferredModel;
|
|
510
|
+
} else {
|
|
511
|
+
delete session.metadata.preferred_model;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
session.updatedAt = /* @__PURE__ */ new Date();
|
|
515
|
+
sessionManager.save(session);
|
|
516
|
+
return getSessionHistory(configPath, normalizedKey, 200);
|
|
517
|
+
}
|
|
518
|
+
function deleteSession(configPath, key) {
|
|
519
|
+
const normalizedKey = normalizeSessionKey(key);
|
|
520
|
+
if (!normalizedKey) {
|
|
521
|
+
return false;
|
|
522
|
+
}
|
|
523
|
+
const config = loadConfigOrDefault(configPath);
|
|
524
|
+
const sessionManager = createSessionManager(config);
|
|
525
|
+
return sessionManager.delete(normalizedKey);
|
|
526
|
+
}
|
|
394
527
|
function updateRuntime(configPath, patch) {
|
|
395
528
|
const config = loadConfigOrDefault(configPath);
|
|
396
529
|
if (patch.agents?.defaults && Object.prototype.hasOwnProperty.call(patch.agents.defaults, "contextTokens")) {
|
|
@@ -495,6 +628,50 @@ function createUiRouter(options) {
|
|
|
495
628
|
options.publish({ type: "config.updated", payload: { path: `channels.${channel}` } });
|
|
496
629
|
return c.json(ok(result));
|
|
497
630
|
});
|
|
631
|
+
app.get("/api/sessions", (c) => {
|
|
632
|
+
const query = c.req.query();
|
|
633
|
+
const q = typeof query.q === "string" ? query.q : void 0;
|
|
634
|
+
const limit = typeof query.limit === "string" ? Number.parseInt(query.limit, 10) : void 0;
|
|
635
|
+
const activeMinutes = typeof query.activeMinutes === "string" ? Number.parseInt(query.activeMinutes, 10) : void 0;
|
|
636
|
+
const data = listSessions(options.configPath, {
|
|
637
|
+
q,
|
|
638
|
+
limit: Number.isFinite(limit) ? limit : void 0,
|
|
639
|
+
activeMinutes: Number.isFinite(activeMinutes) ? activeMinutes : void 0
|
|
640
|
+
});
|
|
641
|
+
return c.json(ok(data));
|
|
642
|
+
});
|
|
643
|
+
app.get("/api/sessions/:key/history", (c) => {
|
|
644
|
+
const key = decodeURIComponent(c.req.param("key"));
|
|
645
|
+
const query = c.req.query();
|
|
646
|
+
const limit = typeof query.limit === "string" ? Number.parseInt(query.limit, 10) : void 0;
|
|
647
|
+
const data = getSessionHistory(options.configPath, key, Number.isFinite(limit) ? limit : void 0);
|
|
648
|
+
if (!data) {
|
|
649
|
+
return c.json(err("NOT_FOUND", `session not found: ${key}`), 404);
|
|
650
|
+
}
|
|
651
|
+
return c.json(ok(data));
|
|
652
|
+
});
|
|
653
|
+
app.put("/api/sessions/:key", async (c) => {
|
|
654
|
+
const key = decodeURIComponent(c.req.param("key"));
|
|
655
|
+
const body = await readJson(c.req.raw);
|
|
656
|
+
if (!body.ok || !body.data || typeof body.data !== "object") {
|
|
657
|
+
return c.json(err("INVALID_BODY", "invalid json body"), 400);
|
|
658
|
+
}
|
|
659
|
+
const data = patchSession(options.configPath, key, body.data);
|
|
660
|
+
if (!data) {
|
|
661
|
+
return c.json(err("NOT_FOUND", `session not found: ${key}`), 404);
|
|
662
|
+
}
|
|
663
|
+
options.publish({ type: "config.updated", payload: { path: "session" } });
|
|
664
|
+
return c.json(ok(data));
|
|
665
|
+
});
|
|
666
|
+
app.delete("/api/sessions/:key", (c) => {
|
|
667
|
+
const key = decodeURIComponent(c.req.param("key"));
|
|
668
|
+
const deleted = deleteSession(options.configPath, key);
|
|
669
|
+
if (!deleted) {
|
|
670
|
+
return c.json(err("NOT_FOUND", `session not found: ${key}`), 404);
|
|
671
|
+
}
|
|
672
|
+
options.publish({ type: "config.updated", payload: { path: "session" } });
|
|
673
|
+
return c.json(ok({ deleted: true }));
|
|
674
|
+
});
|
|
498
675
|
app.put("/api/config/runtime", async (c) => {
|
|
499
676
|
const body = await readJson(c.req.raw);
|
|
500
677
|
if (!body.ok || !body.data || typeof body.data !== "object") {
|
|
@@ -616,8 +793,12 @@ export {
|
|
|
616
793
|
buildConfigSchemaView,
|
|
617
794
|
buildConfigView,
|
|
618
795
|
createUiRouter,
|
|
796
|
+
deleteSession,
|
|
619
797
|
executeConfigAction,
|
|
798
|
+
getSessionHistory,
|
|
799
|
+
listSessions,
|
|
620
800
|
loadConfigOrDefault,
|
|
801
|
+
patchSession,
|
|
621
802
|
startUiServer,
|
|
622
803
|
updateChannel,
|
|
623
804
|
updateModel,
|