@sofer_agent/cli 0.3.6 → 0.3.7
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/chat.d.ts +1 -1
- package/dist/chat.d.ts.map +1 -1
- package/dist/chat.js +55 -4
- package/dist/chat.js.map +1 -1
- package/package.json +2 -2
- package/src/chat.ts +73 -4
package/dist/chat.d.ts
CHANGED
package/dist/chat.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../src/chat.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../src/chat.ts"],"names":[],"mappings":"AAuDA,sEAAsE;AACtE,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAsCjD"}
|
package/dist/chat.js
CHANGED
|
@@ -1,10 +1,57 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
import { agentPaths, loadConfig, shortAgentId, SoferAgent, } from "@sofer_agent/core";
|
|
4
|
+
import { loadSecrets } from "./env.js";
|
|
3
5
|
import { SoferTui } from "./tui.js";
|
|
4
|
-
|
|
6
|
+
function sessionPath(config) {
|
|
7
|
+
if (config.agentObjectId) {
|
|
8
|
+
return agentPaths.agent(shortAgentId(config.agentObjectId)).activityLog;
|
|
9
|
+
}
|
|
10
|
+
if (config.memwal.accountId) {
|
|
11
|
+
return agentPaths.agent(shortAgentId(config.memwal.accountId)).activityLog;
|
|
12
|
+
}
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
function loadSession(path) {
|
|
16
|
+
if (!existsSync(path))
|
|
17
|
+
return [];
|
|
18
|
+
const messages = [];
|
|
19
|
+
const raw = readFileSync(path, "utf8");
|
|
20
|
+
for (const line of raw.split("\n")) {
|
|
21
|
+
if (!line.trim())
|
|
22
|
+
continue;
|
|
23
|
+
try {
|
|
24
|
+
const entry = JSON.parse(line);
|
|
25
|
+
messages.push({ role: entry.role, content: entry.content });
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// skip malformed lines
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return messages;
|
|
32
|
+
}
|
|
33
|
+
function saveSession(path, messages) {
|
|
34
|
+
const lines = messages.map((m) => JSON.stringify({ role: m.role, content: m.content }));
|
|
35
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
36
|
+
writeFileSync(path, `${lines.join("\n")}\n`, "utf8");
|
|
37
|
+
}
|
|
38
|
+
/** Interactive chat TUI with promus-style polish + session resume. */
|
|
5
39
|
export async function chatCommand() {
|
|
6
40
|
const config = loadConfig();
|
|
7
|
-
const
|
|
41
|
+
const secrets = loadSecrets();
|
|
42
|
+
if (!secrets.suiSecretKey || !secrets.anthropicApiKey) {
|
|
43
|
+
console.error("Missing secrets. Run `sofer init` first.");
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
const agent = await SoferAgent.create(config, { suiSecretKey: secrets.suiSecretKey, anthropicApiKey: secrets.anthropicApiKey });
|
|
47
|
+
// Session resume
|
|
48
|
+
const sp = sessionPath(config);
|
|
49
|
+
if (sp) {
|
|
50
|
+
const history = loadSession(sp);
|
|
51
|
+
if (history.length > 0) {
|
|
52
|
+
agent.loadHistory(history);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
8
55
|
const tui = new SoferTui(agent, config);
|
|
9
56
|
await tui.run(async (line, signal) => {
|
|
10
57
|
try {
|
|
@@ -20,6 +67,10 @@ export async function chatCommand() {
|
|
|
20
67
|
tui.addMessage("error", e instanceof Error ? e.message : String(e));
|
|
21
68
|
}
|
|
22
69
|
}
|
|
70
|
+
// Save session after each turn
|
|
71
|
+
if (sp) {
|
|
72
|
+
saveSession(sp, agent.getHistory());
|
|
73
|
+
}
|
|
23
74
|
tui.render();
|
|
24
75
|
});
|
|
25
76
|
}
|
package/dist/chat.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.js","sourceRoot":"","sources":["../src/chat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"chat.js","sourceRoot":"","sources":["../src/chat.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sofer_agent/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"sofer": "./dist/bin.js"
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@clack/prompts": "^1.5.1",
|
|
29
|
-
"@sofer_agent/core": "0.3.
|
|
29
|
+
"@sofer_agent/core": "0.3.2"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@types/node": "^22.10.2",
|
package/src/chat.ts
CHANGED
|
@@ -1,11 +1,76 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
import {
|
|
4
|
+
agentPaths,
|
|
5
|
+
type SoferConfig,
|
|
6
|
+
loadConfig,
|
|
7
|
+
shortAgentId,
|
|
8
|
+
SoferAgent,
|
|
9
|
+
} from "@sofer_agent/core";
|
|
10
|
+
import { loadSecrets } from "./env.js";
|
|
3
11
|
import { SoferTui } from "./tui.js";
|
|
4
12
|
|
|
5
|
-
/**
|
|
13
|
+
/** Serializable message for JSONL session storage. */
|
|
14
|
+
interface SessionMessage {
|
|
15
|
+
role: string;
|
|
16
|
+
content: unknown; // Anthropic ContentBlock[]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface SessionLine {
|
|
20
|
+
role: SessionMessage["role"];
|
|
21
|
+
content: SessionMessage["content"];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function sessionPath(config: SoferConfig): string | null {
|
|
25
|
+
if (config.agentObjectId) {
|
|
26
|
+
return agentPaths.agent(shortAgentId(config.agentObjectId)).activityLog;
|
|
27
|
+
}
|
|
28
|
+
if (config.memwal.accountId) {
|
|
29
|
+
return agentPaths.agent(shortAgentId(config.memwal.accountId)).activityLog;
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function loadSession(path: string): SessionMessage[] {
|
|
35
|
+
if (!existsSync(path)) return [];
|
|
36
|
+
const messages: SessionMessage[] = [];
|
|
37
|
+
const raw = readFileSync(path, "utf8");
|
|
38
|
+
for (const line of raw.split("\n")) {
|
|
39
|
+
if (!line.trim()) continue;
|
|
40
|
+
try {
|
|
41
|
+
const entry = JSON.parse(line) as SessionLine;
|
|
42
|
+
messages.push({ role: entry.role, content: entry.content });
|
|
43
|
+
} catch {
|
|
44
|
+
// skip malformed lines
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return messages;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function saveSession(path: string, messages: SessionMessage[]): void {
|
|
51
|
+
const lines = messages.map((m) => JSON.stringify({ role: m.role, content: m.content }));
|
|
52
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
53
|
+
writeFileSync(path, `${lines.join("\n")}\n`, "utf8");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Interactive chat TUI with promus-style polish + session resume. */
|
|
6
57
|
export async function chatCommand(): Promise<void> {
|
|
7
58
|
const config = loadConfig();
|
|
8
|
-
const
|
|
59
|
+
const secrets = loadSecrets();
|
|
60
|
+
if (!secrets.suiSecretKey || !secrets.anthropicApiKey) {
|
|
61
|
+
console.error("Missing secrets. Run `sofer init` first.");
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
const agent = await SoferAgent.create(config, { suiSecretKey: secrets.suiSecretKey, anthropicApiKey: secrets.anthropicApiKey });
|
|
65
|
+
|
|
66
|
+
// Session resume
|
|
67
|
+
const sp = sessionPath(config);
|
|
68
|
+
if (sp) {
|
|
69
|
+
const history = loadSession(sp);
|
|
70
|
+
if (history.length > 0) {
|
|
71
|
+
agent.loadHistory(history);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
9
74
|
|
|
10
75
|
const tui = new SoferTui(agent, config);
|
|
11
76
|
|
|
@@ -21,6 +86,10 @@ export async function chatCommand(): Promise<void> {
|
|
|
21
86
|
tui.addMessage("error", e instanceof Error ? e.message : String(e));
|
|
22
87
|
}
|
|
23
88
|
}
|
|
89
|
+
// Save session after each turn
|
|
90
|
+
if (sp) {
|
|
91
|
+
saveSession(sp, agent.getHistory());
|
|
92
|
+
}
|
|
24
93
|
tui.render();
|
|
25
94
|
});
|
|
26
95
|
}
|