@averyyy/pi-coding-agent 0.80.3-piclient.6 → 0.80.3-piclient.8
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 +1 -0
- package/dist/core/agent-session.d.ts +5 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +119 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/pi-server-client.d.ts +2 -0
- package/dist/core/pi-server-client.d.ts.map +1 -1
- package/dist/core/pi-server-client.js +86 -21
- package/dist/core/pi-server-client.js.map +1 -1
- package/dist/core/pi-server-protocol.d.ts +13 -0
- package/dist/core/pi-server-protocol.d.ts.map +1 -0
- package/dist/core/pi-server-protocol.js +32 -0
- package/dist/core/pi-server-protocol.js.map +1 -0
- package/dist/core/pi-server-request.d.ts.map +1 -1
- package/dist/core/pi-server-request.js +56 -16
- package/dist/core/pi-server-request.js.map +1 -1
- package/dist/core/sdk.d.ts +8 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +17 -24
- package/dist/core/sdk.js.map +1 -1
- package/package.json +4 -4
|
@@ -67,6 +67,9 @@ const INTRA_TURN_COMPACTION_MARKER_TEXT = "Continue from the compaction summary
|
|
|
67
67
|
const VALIDATION_HINT_MESSAGE_TYPE = "pi:validation-hint";
|
|
68
68
|
const VALIDATION_HINT_FILE_LIMIT = 12;
|
|
69
69
|
const VALIDATION_HINT_FAILURE_CHAR_LIMIT = 1200;
|
|
70
|
+
const AUTO_SESSION_NAME_INPUT_CHAR_LIMIT = 4000;
|
|
71
|
+
const AUTO_SESSION_NAME_MAX_CHARS = 80;
|
|
72
|
+
const AUTO_SESSION_NAME_PROMPT = "Name this coding session from the transcript below. Return only a concise title, in the user's language when clear. No quotes, no markdown, no explanation. Do not call tools.";
|
|
70
73
|
function isPiServerMode() {
|
|
71
74
|
return process.env.PI_SERVER_MODE === "true";
|
|
72
75
|
}
|
|
@@ -79,6 +82,16 @@ function getStringField(input, key) {
|
|
|
79
82
|
const value = input[key];
|
|
80
83
|
return typeof value === "string" && value.trim().length > 0 ? value : undefined;
|
|
81
84
|
}
|
|
85
|
+
function getPiServerFailurePhase(message) {
|
|
86
|
+
for (const diagnostic of message.diagnostics ?? []) {
|
|
87
|
+
if (diagnostic.type !== "pi_server_failure")
|
|
88
|
+
continue;
|
|
89
|
+
const phase = diagnostic.details?.phase;
|
|
90
|
+
if (typeof phase === "string")
|
|
91
|
+
return phase;
|
|
92
|
+
}
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
82
95
|
function toolTextContent(content) {
|
|
83
96
|
return content
|
|
84
97
|
.filter((part) => part.type === "text")
|
|
@@ -92,6 +105,41 @@ function compactValidationSummary(text) {
|
|
|
92
105
|
return trimmed;
|
|
93
106
|
return `...${trimmed.slice(trimmed.length - VALIDATION_HINT_FAILURE_CHAR_LIMIT + 3)}`;
|
|
94
107
|
}
|
|
108
|
+
function messageTextContent(message) {
|
|
109
|
+
if (!("content" in message))
|
|
110
|
+
return "";
|
|
111
|
+
const content = message.content;
|
|
112
|
+
if (typeof content === "string")
|
|
113
|
+
return content;
|
|
114
|
+
if (!Array.isArray(content))
|
|
115
|
+
return "";
|
|
116
|
+
return content
|
|
117
|
+
.filter((part) => part.type === "text")
|
|
118
|
+
.map((part) => part.text)
|
|
119
|
+
.join("\n")
|
|
120
|
+
.trim();
|
|
121
|
+
}
|
|
122
|
+
function truncateForSessionNameInput(text) {
|
|
123
|
+
if (text.length <= AUTO_SESSION_NAME_INPUT_CHAR_LIMIT)
|
|
124
|
+
return text;
|
|
125
|
+
return text.slice(0, AUTO_SESSION_NAME_INPUT_CHAR_LIMIT).trim();
|
|
126
|
+
}
|
|
127
|
+
function sanitizeGeneratedSessionName(text) {
|
|
128
|
+
const firstLine = text
|
|
129
|
+
.split(/\r?\n/u)
|
|
130
|
+
.map((line) => line.trim())
|
|
131
|
+
.find((line) => line.length > 0);
|
|
132
|
+
if (!firstLine)
|
|
133
|
+
return undefined;
|
|
134
|
+
const title = firstLine
|
|
135
|
+
.replace(/^title:\s*/iu, "")
|
|
136
|
+
.replace(/^["'`]+|["'`]+$/g, "")
|
|
137
|
+
.replace(/\s+/g, " ")
|
|
138
|
+
.trim();
|
|
139
|
+
if (!title)
|
|
140
|
+
return undefined;
|
|
141
|
+
return title.length > AUTO_SESSION_NAME_MAX_CHARS ? title.slice(0, AUTO_SESSION_NAME_MAX_CHARS).trim() : title;
|
|
142
|
+
}
|
|
95
143
|
// ============================================================================
|
|
96
144
|
// AgentSession Class
|
|
97
145
|
// ============================================================================
|
|
@@ -144,6 +192,7 @@ export class AgentSession {
|
|
|
144
192
|
_extensionShutdownHandler;
|
|
145
193
|
_extensionErrorListener;
|
|
146
194
|
_extensionErrorUnsubscriber;
|
|
195
|
+
_autoSessionNameAttempted = false;
|
|
147
196
|
// Model registry for API key resolution
|
|
148
197
|
_modelRegistry;
|
|
149
198
|
// Tool registry for extension getTools/setTools
|
|
@@ -883,12 +932,79 @@ export class AgentSession {
|
|
|
883
932
|
throw error;
|
|
884
933
|
}
|
|
885
934
|
}
|
|
935
|
+
await this._maybeGenerateSessionName();
|
|
886
936
|
}
|
|
887
937
|
finally {
|
|
888
938
|
this._systemPromptOverride = undefined;
|
|
889
939
|
this._flushPendingBashMessages();
|
|
890
940
|
}
|
|
891
941
|
}
|
|
942
|
+
_sessionHasInfoEntry() {
|
|
943
|
+
return this.sessionManager.getEntries().some((entry) => entry.type === "session_info");
|
|
944
|
+
}
|
|
945
|
+
_buildSessionNameTranscript() {
|
|
946
|
+
const lines = [];
|
|
947
|
+
for (const message of this.agent.state.messages) {
|
|
948
|
+
if (message.role !== "user" && message.role !== "assistant")
|
|
949
|
+
continue;
|
|
950
|
+
const text = messageTextContent(message);
|
|
951
|
+
if (!text)
|
|
952
|
+
continue;
|
|
953
|
+
lines.push(`${message.role === "user" ? "User" : "Assistant"}: ${text}`);
|
|
954
|
+
}
|
|
955
|
+
const transcript = lines.join("\n\n").trim();
|
|
956
|
+
return transcript ? truncateForSessionNameInput(transcript) : undefined;
|
|
957
|
+
}
|
|
958
|
+
_shouldGenerateSessionName() {
|
|
959
|
+
if (this._autoSessionNameAttempted || this._sessionHasInfoEntry())
|
|
960
|
+
return false;
|
|
961
|
+
const userMessages = this.agent.state.messages.filter((message) => message.role === "user");
|
|
962
|
+
if (userMessages.length !== 1)
|
|
963
|
+
return false;
|
|
964
|
+
const lastAssistant = this._findLastAssistantMessage();
|
|
965
|
+
return lastAssistant !== undefined && !this._isTerminalAssistantFailure(lastAssistant);
|
|
966
|
+
}
|
|
967
|
+
async _maybeGenerateSessionName() {
|
|
968
|
+
if (!this._shouldGenerateSessionName())
|
|
969
|
+
return;
|
|
970
|
+
this._autoSessionNameAttempted = true;
|
|
971
|
+
const model = this.model;
|
|
972
|
+
const transcript = this._buildSessionNameTranscript();
|
|
973
|
+
if (!model || !transcript)
|
|
974
|
+
return;
|
|
975
|
+
try {
|
|
976
|
+
const stream = await this.agent.streamFn(model, {
|
|
977
|
+
systemPrompt: this.systemPrompt,
|
|
978
|
+
messages: [
|
|
979
|
+
{
|
|
980
|
+
role: "user",
|
|
981
|
+
content: [{ type: "text", text: `${AUTO_SESSION_NAME_PROMPT}\n\n${transcript}` }],
|
|
982
|
+
timestamp: Date.now(),
|
|
983
|
+
},
|
|
984
|
+
],
|
|
985
|
+
tools: this.agent.state.tools,
|
|
986
|
+
}, {
|
|
987
|
+
maxTokens: 32,
|
|
988
|
+
reasoning: undefined,
|
|
989
|
+
sessionId: this.sessionId,
|
|
990
|
+
transport: this.agent.transport,
|
|
991
|
+
thinkingBudgets: this.agent.thinkingBudgets,
|
|
992
|
+
maxRetryDelayMs: this.agent.maxRetryDelayMs,
|
|
993
|
+
});
|
|
994
|
+
for await (const _event of stream) {
|
|
995
|
+
// Drain the title stream without surfacing it as a chat message.
|
|
996
|
+
}
|
|
997
|
+
const response = await stream.result();
|
|
998
|
+
if (response.stopReason === "error" || response.stopReason === "aborted")
|
|
999
|
+
return;
|
|
1000
|
+
const title = sanitizeGeneratedSessionName(messageTextContent(response));
|
|
1001
|
+
if (title)
|
|
1002
|
+
this.setSessionName(title);
|
|
1003
|
+
}
|
|
1004
|
+
catch {
|
|
1005
|
+
// Session naming is a post-turn convenience; the completed assistant turn stays authoritative.
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
892
1008
|
async _handlePostAgentRun() {
|
|
893
1009
|
const msg = this._lastAssistantMessage;
|
|
894
1010
|
this._lastAssistantMessage = undefined;
|
|
@@ -2345,6 +2461,9 @@ export class AgentSession {
|
|
|
2345
2461
|
return false;
|
|
2346
2462
|
if (this._isPostAssistantPiServerSyncFailure(message))
|
|
2347
2463
|
return false;
|
|
2464
|
+
const piServerPhase = getPiServerFailurePhase(message);
|
|
2465
|
+
if (piServerPhase && piServerPhase !== "provider_stream")
|
|
2466
|
+
return false;
|
|
2348
2467
|
if (message.errorMessage && this._isNonRetryableProviderLimitError(message.errorMessage))
|
|
2349
2468
|
return false;
|
|
2350
2469
|
return isRetryableAssistantError(message);
|