@nextclaw/server 0.4.10 → 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 +46 -1
- package/dist/index.js +191 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -32,6 +32,7 @@ type AgentProfileView = {
|
|
|
32
32
|
workspace?: string;
|
|
33
33
|
model?: string;
|
|
34
34
|
maxTokens?: number;
|
|
35
|
+
contextTokens?: number;
|
|
35
36
|
maxToolIterations?: number;
|
|
36
37
|
};
|
|
37
38
|
type BindingPeerView = {
|
|
@@ -52,8 +53,43 @@ type SessionConfigView = {
|
|
|
52
53
|
maxPingPongTurns?: number;
|
|
53
54
|
};
|
|
54
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
|
+
};
|
|
55
88
|
type RuntimeConfigUpdate = {
|
|
56
89
|
agents?: {
|
|
90
|
+
defaults?: {
|
|
91
|
+
contextTokens?: number;
|
|
92
|
+
};
|
|
57
93
|
list?: AgentProfileView[];
|
|
58
94
|
};
|
|
59
95
|
bindings?: AgentBindingView[];
|
|
@@ -65,6 +101,7 @@ type ConfigView = {
|
|
|
65
101
|
model: string;
|
|
66
102
|
workspace?: string;
|
|
67
103
|
maxTokens?: number;
|
|
104
|
+
contextTokens?: number;
|
|
68
105
|
maxToolIterations?: number;
|
|
69
106
|
};
|
|
70
107
|
list?: AgentProfileView[];
|
|
@@ -234,6 +271,14 @@ declare function loadConfigOrDefault(configPath: string): Config;
|
|
|
234
271
|
declare function updateModel(configPath: string, model: string): ConfigView;
|
|
235
272
|
declare function updateProvider(configPath: string, providerName: string, patch: ProviderConfigUpdate): ProviderConfigView | null;
|
|
236
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;
|
|
237
282
|
declare function updateRuntime(configPath: string, patch: RuntimeConfigUpdate): Pick<ConfigView, "agents" | "bindings" | "session">;
|
|
238
283
|
|
|
239
|
-
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,8 +393,145 @@ 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);
|
|
529
|
+
if (patch.agents?.defaults && Object.prototype.hasOwnProperty.call(patch.agents.defaults, "contextTokens")) {
|
|
530
|
+
const nextContextTokens = patch.agents.defaults.contextTokens;
|
|
531
|
+
if (typeof nextContextTokens === "number" && Number.isFinite(nextContextTokens)) {
|
|
532
|
+
config.agents.defaults.contextTokens = Math.max(1e3, Math.trunc(nextContextTokens));
|
|
533
|
+
}
|
|
534
|
+
}
|
|
396
535
|
if (patch.agents && Object.prototype.hasOwnProperty.call(patch.agents, "list")) {
|
|
397
536
|
config.agents.list = (patch.agents.list ?? []).map((entry) => ({
|
|
398
537
|
...entry,
|
|
@@ -489,12 +628,59 @@ function createUiRouter(options) {
|
|
|
489
628
|
options.publish({ type: "config.updated", payload: { path: `channels.${channel}` } });
|
|
490
629
|
return c.json(ok(result));
|
|
491
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
|
+
});
|
|
492
675
|
app.put("/api/config/runtime", async (c) => {
|
|
493
676
|
const body = await readJson(c.req.raw);
|
|
494
677
|
if (!body.ok || !body.data || typeof body.data !== "object") {
|
|
495
678
|
return c.json(err("INVALID_BODY", "invalid json body"), 400);
|
|
496
679
|
}
|
|
497
680
|
const result = updateRuntime(options.configPath, body.data);
|
|
681
|
+
if (body.data.agents?.defaults && Object.prototype.hasOwnProperty.call(body.data.agents.defaults, "contextTokens")) {
|
|
682
|
+
options.publish({ type: "config.updated", payload: { path: "agents.defaults.contextTokens" } });
|
|
683
|
+
}
|
|
498
684
|
options.publish({ type: "config.updated", payload: { path: "agents.list" } });
|
|
499
685
|
options.publish({ type: "config.updated", payload: { path: "bindings" } });
|
|
500
686
|
options.publish({ type: "config.updated", payload: { path: "session" } });
|
|
@@ -607,8 +793,12 @@ export {
|
|
|
607
793
|
buildConfigSchemaView,
|
|
608
794
|
buildConfigView,
|
|
609
795
|
createUiRouter,
|
|
796
|
+
deleteSession,
|
|
610
797
|
executeConfigAction,
|
|
798
|
+
getSessionHistory,
|
|
799
|
+
listSessions,
|
|
611
800
|
loadConfigOrDefault,
|
|
801
|
+
patchSession,
|
|
612
802
|
startUiServer,
|
|
613
803
|
updateChannel,
|
|
614
804
|
updateModel,
|