@oh-my-pi/pi-coding-agent 11.0.0 → 11.0.2
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 +6 -0
- package/package.json +7 -7
- package/src/session/agent-session.ts +4 -3
- package/src/session/session-manager.ts +57 -55
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
3
|
-
"version": "11.0.
|
|
3
|
+
"version": "11.0.2",
|
|
4
4
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"ompConfig": {
|
|
@@ -80,12 +80,12 @@
|
|
|
80
80
|
},
|
|
81
81
|
"dependencies": {
|
|
82
82
|
"@mozilla/readability": "0.6.0",
|
|
83
|
-
"@oh-my-pi/omp-stats": "11.0.
|
|
84
|
-
"@oh-my-pi/pi-agent-core": "11.0.
|
|
85
|
-
"@oh-my-pi/pi-ai": "11.0.
|
|
86
|
-
"@oh-my-pi/pi-natives": "11.0.
|
|
87
|
-
"@oh-my-pi/pi-tui": "11.0.
|
|
88
|
-
"@oh-my-pi/pi-utils": "11.0.
|
|
83
|
+
"@oh-my-pi/omp-stats": "11.0.2",
|
|
84
|
+
"@oh-my-pi/pi-agent-core": "11.0.2",
|
|
85
|
+
"@oh-my-pi/pi-ai": "11.0.2",
|
|
86
|
+
"@oh-my-pi/pi-natives": "11.0.2",
|
|
87
|
+
"@oh-my-pi/pi-tui": "11.0.2",
|
|
88
|
+
"@oh-my-pi/pi-utils": "11.0.2",
|
|
89
89
|
"@openai/agents": "^0.4.5",
|
|
90
90
|
"@sinclair/typebox": "^0.34.48",
|
|
91
91
|
"ajv": "^8.17.1",
|
|
@@ -33,7 +33,7 @@ import { YAML } from "bun";
|
|
|
33
33
|
import type { Rule } from "../capability/rule";
|
|
34
34
|
import { getAgentDbPath } from "../config";
|
|
35
35
|
import { MODEL_ROLE_IDS, type ModelRegistry, type ModelRole } from "../config/model-registry";
|
|
36
|
-
import { parseModelString } from "../config/model-resolver";
|
|
36
|
+
import { expandRoleAlias, parseModelString } from "../config/model-resolver";
|
|
37
37
|
import {
|
|
38
38
|
expandPromptTemplate,
|
|
39
39
|
type PromptTemplate,
|
|
@@ -1871,13 +1871,14 @@ export class AgentSession {
|
|
|
1871
1871
|
: this.settings.getModelRole(role);
|
|
1872
1872
|
if (!roleModelStr) continue;
|
|
1873
1873
|
|
|
1874
|
-
const
|
|
1874
|
+
const expandedRoleModelStr = expandRoleAlias(roleModelStr, this.settings);
|
|
1875
|
+
const parsed = parseModelString(expandedRoleModelStr);
|
|
1875
1876
|
let match: Model | undefined;
|
|
1876
1877
|
if (parsed) {
|
|
1877
1878
|
match = availableModels.find(m => m.provider === parsed.provider && m.id === parsed.id);
|
|
1878
1879
|
}
|
|
1879
1880
|
if (!match) {
|
|
1880
|
-
match = availableModels.find(m => m.id.toLowerCase() ===
|
|
1881
|
+
match = availableModels.find(m => m.id.toLowerCase() === expandedRoleModelStr.toLowerCase());
|
|
1881
1882
|
}
|
|
1882
1883
|
if (!match) continue;
|
|
1883
1884
|
|
|
@@ -579,23 +579,22 @@ function extractFirstUserPrompt(entries: Array<Record<string, unknown>>): string
|
|
|
579
579
|
async function getSortedSessions(sessionDir: string, storage: SessionStorage): Promise<RecentSessionInfo[]> {
|
|
580
580
|
try {
|
|
581
581
|
const files: string[] = storage.listFilesSync(sessionDir, "*.jsonl");
|
|
582
|
-
const
|
|
582
|
+
const sessions: RecentSessionInfo[] = [];
|
|
583
|
+
await Promise.all(
|
|
583
584
|
files.map(async (path: string) => {
|
|
584
585
|
try {
|
|
585
586
|
const content = await storage.readTextPrefix(path, 4096);
|
|
586
587
|
const entries = parseJsonlEntries<Record<string, unknown>>(content);
|
|
587
|
-
if (entries.length === 0) return
|
|
588
|
+
if (entries.length === 0) return;
|
|
588
589
|
const header = entries[0] as Record<string, unknown>;
|
|
589
|
-
if (header.type !== "session" || typeof header.id !== "string") return
|
|
590
|
+
if (header.type !== "session" || typeof header.id !== "string") return;
|
|
590
591
|
const mtime = storage.statSync(path).mtimeMs;
|
|
591
592
|
const firstPrompt = header.title ? undefined : extractFirstUserPrompt(entries);
|
|
592
|
-
|
|
593
|
-
} catch {
|
|
594
|
-
return null;
|
|
595
|
-
}
|
|
593
|
+
sessions.push(new RecentSessionInfo(path, mtime, header, firstPrompt));
|
|
594
|
+
} catch {}
|
|
596
595
|
}),
|
|
597
596
|
);
|
|
598
|
-
return
|
|
597
|
+
return sessions.sort((a, b) => b.mtime - a.mtime);
|
|
599
598
|
} catch {
|
|
600
599
|
return [];
|
|
601
600
|
}
|
|
@@ -908,62 +907,65 @@ function extractTextFromContent(content: Message["content"]): string {
|
|
|
908
907
|
async function collectSessionsFromFiles(files: string[], storage: SessionStorage): Promise<SessionInfo[]> {
|
|
909
908
|
const sessions: SessionInfo[] = [];
|
|
910
909
|
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
910
|
+
// Collect session info for all files in parallel
|
|
911
|
+
await Promise.all(
|
|
912
|
+
files.map(async file => {
|
|
913
|
+
try {
|
|
914
|
+
const content = await storage.readText(file);
|
|
915
|
+
const entries = parseJsonlEntries<Record<string, unknown>>(content);
|
|
916
|
+
if (entries.length === 0) return;
|
|
917
|
+
|
|
918
|
+
// Check first entry for valid session header
|
|
919
|
+
type SessionHeaderShape = { type: string; id: string; cwd?: string; title?: string; timestamp: string };
|
|
920
|
+
const header = entries[0] as SessionHeaderShape;
|
|
921
|
+
if (header.type !== "session" || !header.id) return;
|
|
922
|
+
|
|
923
|
+
let messageCount = 0;
|
|
924
|
+
let firstMessage = "";
|
|
925
|
+
const allMessages: string[] = [];
|
|
926
|
+
let shortSummary: string | undefined;
|
|
927
|
+
|
|
928
|
+
for (let i = 1; i < entries.length; i++) {
|
|
929
|
+
const entry = entries[i] as { type?: string; message?: Message; shortSummary?: string };
|
|
930
|
+
|
|
931
|
+
if (entry.type === "compaction" && typeof entry.shortSummary === "string") {
|
|
932
|
+
shortSummary = entry.shortSummary;
|
|
933
|
+
}
|
|
934
934
|
|
|
935
|
-
|
|
936
|
-
|
|
935
|
+
if (entry.type === "message" && entry.message) {
|
|
936
|
+
messageCount++;
|
|
937
937
|
|
|
938
|
-
|
|
939
|
-
|
|
938
|
+
if (entry.message.role === "user" || entry.message.role === "assistant") {
|
|
939
|
+
const textContent = extractTextFromContent(entry.message.content);
|
|
940
940
|
|
|
941
|
-
|
|
942
|
-
|
|
941
|
+
if (textContent) {
|
|
942
|
+
allMessages.push(textContent);
|
|
943
943
|
|
|
944
|
-
|
|
945
|
-
|
|
944
|
+
if (!firstMessage && entry.message.role === "user") {
|
|
945
|
+
firstMessage = textContent;
|
|
946
|
+
}
|
|
946
947
|
}
|
|
947
948
|
}
|
|
948
949
|
}
|
|
949
950
|
}
|
|
950
|
-
}
|
|
951
951
|
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
952
|
+
if (messageCount) {
|
|
953
|
+
const stats = storage.statSync(file);
|
|
954
|
+
sessions.push({
|
|
955
|
+
path: file,
|
|
956
|
+
id: header.id,
|
|
957
|
+
cwd: typeof header.cwd === "string" ? header.cwd : "",
|
|
958
|
+
title: header.title ?? shortSummary,
|
|
959
|
+
created: new Date(header.timestamp),
|
|
960
|
+
modified: stats.mtime,
|
|
961
|
+
messageCount,
|
|
962
|
+
firstMessage: firstMessage || "(no messages)",
|
|
963
|
+
allMessagesText: allMessages.join(" "),
|
|
964
|
+
});
|
|
965
|
+
}
|
|
966
|
+
} catch {}
|
|
967
|
+
}),
|
|
968
|
+
);
|
|
967
969
|
|
|
968
970
|
sessions.sort((a, b) => b.modified.getTime() - a.modified.getTime());
|
|
969
971
|
return sessions;
|