@code-yeongyu/senpi 2026.8.21 → 2026.8.22-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 +69 -0
- package/dist/bun-runtime.d.ts +58 -0
- package/dist/bun-runtime.d.ts.map +1 -0
- package/dist/bun-runtime.js +163 -0
- package/dist/bun-runtime.js.map +1 -0
- package/dist/cli.js +45 -2
- package/dist/cli.js.map +1 -1
- package/dist/core/agent-session.d.ts +7 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +81 -26
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/agent-settled-delivery.d.ts +13 -1
- package/dist/core/agent-settled-delivery.d.ts.map +1 -1
- package/dist/core/agent-settled-delivery.js +33 -2
- package/dist/core/agent-settled-delivery.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +5 -4
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/extensions/builtin/goal/cache-warm-renderer.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/cache-warm-renderer.js +2 -3
- package/dist/core/extensions/builtin/goal/cache-warm-renderer.js.map +1 -1
- package/dist/core/extensions/builtin/goal/cache-warm.d.ts +6 -0
- package/dist/core/extensions/builtin/goal/cache-warm.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/cache-warm.js +43 -0
- package/dist/core/extensions/builtin/goal/cache-warm.js.map +1 -1
- package/dist/core/extensions/builtin/permission-system/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/permission-system/index.js +7 -11
- package/dist/core/extensions/builtin/permission-system/index.js.map +1 -1
- package/dist/core/model-resolver.js +2 -2
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/session-work-barrier.d.ts.map +1 -1
- package/dist/core/session-work-barrier.js +38 -1
- package/dist/core/session-work-barrier.js.map +1 -1
- package/dist/modes/interactive/components/status-indicator.d.ts +3 -0
- package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
- package/dist/modes/interactive/components/status-indicator.js +7 -1
- package/dist/modes/interactive/components/status-indicator.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +4 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +118 -38
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/senpi +45 -2
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +58 -0
- package/node_modules/@code-yeongyu/senpi-codemode/README.md +5 -0
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/extension/runtime-factory.ts +4 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/extension/runtime-info.ts +41 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/extension/session-manager.ts +8 -3
- package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +4 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/interpreters/detect.ts +17 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/interpreters/resolve-command.ts +68 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-kernel.ts +15 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/timeouts/idle-timeout.ts +33 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/cell-runtime.ts +5 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool-options.ts +3 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +2 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/render.ts +60 -3
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/runtime-label.ts +49 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/types.ts +13 -0
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/stream-retry.d.ts +21 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/stream-retry.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/stream-retry.js +36 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/stream-retry.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/types.d.ts +10 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts +6 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js +166 -26
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/github-copilot.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/google.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
- package/dist/modes/interactive/split-trailing-assistant-text.d.ts +0 -7
- package/dist/modes/interactive/split-trailing-assistant-text.d.ts.map +0 -1
- package/dist/modes/interactive/split-trailing-assistant-text.js +0 -19
- package/dist/modes/interactive/split-trailing-assistant-text.js.map +0 -1
|
@@ -27,7 +27,7 @@ import { resolvePath } from "../utils/paths.js";
|
|
|
27
27
|
import { sleep } from "../utils/sleep.js";
|
|
28
28
|
import { normalizeToolResultImages } from "../utils/tool-result-images.js";
|
|
29
29
|
import { AgentAbortProvenance } from "./agent-abort-provenance.js";
|
|
30
|
-
import { AgentSettledDelivery } from "./agent-settled-delivery.js";
|
|
30
|
+
import { AgentSettledDelivery, } from "./agent-settled-delivery.js";
|
|
31
31
|
import { formatNoApiKeyFoundMessage, formatNoModelSelectedMessage } from "./auth-guidance.js";
|
|
32
32
|
import { executeBashWithOperations } from "./bash-executor.js";
|
|
33
33
|
import { envValue } from "./brand.js";
|
|
@@ -327,6 +327,7 @@ export class AgentSession {
|
|
|
327
327
|
this._toolExecutionDepth = 0;
|
|
328
328
|
this._promptStartPending = false;
|
|
329
329
|
this._nextInputId = 0;
|
|
330
|
+
this._settlementEpoch = 0;
|
|
330
331
|
/** Tracks pending steering messages for UI display. Removed when delivered. */
|
|
331
332
|
this._steeringMessages = [];
|
|
332
333
|
/** Tracks pending follow-up messages for UI display. Removed when delivered. */
|
|
@@ -992,13 +993,15 @@ export class AgentSession {
|
|
|
992
993
|
}
|
|
993
994
|
this._isAgentRunActive = false;
|
|
994
995
|
let deferredActions = [];
|
|
996
|
+
let deferredTurnClaims = [];
|
|
995
997
|
this._agentSettledDelivery.begin(this._userAbortGeneration);
|
|
998
|
+
const settlementEpoch = ++this._settlementEpoch;
|
|
996
999
|
try {
|
|
997
1000
|
await this._extensionRunner.emit({ type: "agent_settled" });
|
|
998
1001
|
this._emit({ type: "agent_settled" });
|
|
999
1002
|
if (this._abortProvenance.takeLateUserJoin())
|
|
1000
1003
|
await this._emitSessionAbort();
|
|
1001
|
-
deferredActions = this._agentSettledDelivery.finish(this._userAbortGeneration);
|
|
1004
|
+
({ actions: deferredActions, turnClaims: deferredTurnClaims } = this._agentSettledDelivery.finish(this._userAbortGeneration));
|
|
1002
1005
|
}
|
|
1003
1006
|
finally {
|
|
1004
1007
|
this._agentSettledDelivery.cancel();
|
|
@@ -1007,8 +1010,25 @@ export class AgentSession {
|
|
|
1007
1010
|
}
|
|
1008
1011
|
for (const action of deferredActions)
|
|
1009
1012
|
action();
|
|
1013
|
+
queueMicrotask(() => {
|
|
1014
|
+
void this._emitAgentIdleAfterDeferredTurns(settlementEpoch, deferredTurnClaims);
|
|
1015
|
+
});
|
|
1016
|
+
}
|
|
1017
|
+
async _emitAgentIdleAfterDeferredTurns(settlementEpoch, deferredTurnClaims) {
|
|
1018
|
+
const dispositions = await Promise.all(deferredTurnClaims.map((claim) => claim.disposition));
|
|
1019
|
+
if (dispositions.includes("started"))
|
|
1020
|
+
return;
|
|
1021
|
+
if (dispositions.includes("delegated") || this._sessionWorkBarrier.hasActiveWork) {
|
|
1022
|
+
await this._waitForSettledSessionWork();
|
|
1023
|
+
}
|
|
1024
|
+
if (settlementEpoch !== this._settlementEpoch)
|
|
1025
|
+
return;
|
|
1026
|
+
if (this._isAgentRunActive || this._sessionWorkBarrier.hasActiveWork)
|
|
1027
|
+
return;
|
|
1028
|
+
this._emit({ type: "agent_idle" });
|
|
1010
1029
|
}
|
|
1011
|
-
async _promptAgent(messages) {
|
|
1030
|
+
async _promptAgent(messages, deferredTurnClaim) {
|
|
1031
|
+
deferredTurnClaim?.resolve("started");
|
|
1012
1032
|
this._isAgentRunActive = true;
|
|
1013
1033
|
this._requiredCompactionAdmissionError = undefined;
|
|
1014
1034
|
this.agent.abortServerSideFallback =
|
|
@@ -2908,7 +2928,7 @@ export class AgentSession {
|
|
|
2908
2928
|
* @param options.triggerTurn If true and not streaming, triggers a new LLM turn
|
|
2909
2929
|
* @param options.deliverAs Delivery mode: "steer", "followUp", or "nextTurn"
|
|
2910
2930
|
*/
|
|
2911
|
-
async sendCustomMessage(message, options) {
|
|
2931
|
+
async sendCustomMessage(message, options, deferredTurnClaim) {
|
|
2912
2932
|
const userAbortGeneration = this._userAbortGeneration;
|
|
2913
2933
|
const appMessage = {
|
|
2914
2934
|
role: "custom",
|
|
@@ -2941,6 +2961,7 @@ export class AgentSession {
|
|
|
2941
2961
|
this._pendingNextTurnMessages.push(appMessage);
|
|
2942
2962
|
}
|
|
2943
2963
|
else if (this.isStreaming && options?.triggerTurn !== false) {
|
|
2964
|
+
deferredTurnClaim?.resolve("delegated");
|
|
2944
2965
|
if (options?.deliverAs === "followUp") {
|
|
2945
2966
|
this.agent.followUp(appMessage);
|
|
2946
2967
|
}
|
|
@@ -2953,6 +2974,7 @@ export class AgentSession {
|
|
|
2953
2974
|
(activeCompactionGeneration !== undefined &&
|
|
2954
2975
|
this._compactionLifecycle.state.generation === activeCompactionGeneration &&
|
|
2955
2976
|
this._compactionLifecycle.state.status !== "completed"))) {
|
|
2977
|
+
deferredTurnClaim?.resolve("delegated");
|
|
2956
2978
|
if (options?.deliverAs === "followUp") {
|
|
2957
2979
|
this.agent.followUp(appMessage);
|
|
2958
2980
|
}
|
|
@@ -2978,7 +3000,7 @@ export class AgentSession {
|
|
|
2978
3000
|
}
|
|
2979
3001
|
throw error;
|
|
2980
3002
|
}
|
|
2981
|
-
await this._promptAgent(appMessage);
|
|
3003
|
+
await this._promptAgent(appMessage, deferredTurnClaim);
|
|
2982
3004
|
}
|
|
2983
3005
|
else {
|
|
2984
3006
|
this.agent.state.messages.push(appMessage);
|
|
@@ -2989,6 +3011,7 @@ export class AgentSession {
|
|
|
2989
3011
|
}
|
|
2990
3012
|
}
|
|
2991
3013
|
finally {
|
|
3014
|
+
deferredTurnClaim?.resolve("finished-without-start");
|
|
2992
3015
|
finishSessionWork?.();
|
|
2993
3016
|
}
|
|
2994
3017
|
}
|
|
@@ -3003,7 +3026,7 @@ export class AgentSession {
|
|
|
3003
3026
|
* @param options.deliverAs Delivery mode when streaming: "steer" or "followUp"
|
|
3004
3027
|
* @param options.expandPromptTemplates Whether to dispatch extension commands and expand skill commands and prompt templates. Default: false.
|
|
3005
3028
|
*/
|
|
3006
|
-
async sendUserMessage(content, options) {
|
|
3029
|
+
async sendUserMessage(content, options, deferredTurnClaim) {
|
|
3007
3030
|
const bindingPromptReadiness = this._extensionBindingPromptReadiness;
|
|
3008
3031
|
let resolveBindingPromptReadiness;
|
|
3009
3032
|
if (bindingPromptReadiness) {
|
|
@@ -3012,26 +3035,35 @@ export class AgentSession {
|
|
|
3012
3035
|
});
|
|
3013
3036
|
bindingPromptReadiness.add(readiness);
|
|
3014
3037
|
}
|
|
3015
|
-
// Normalize content to text string + optional images
|
|
3038
|
+
// Normalize content to text string + optional images. A throw here (null or a
|
|
3039
|
+
// content array whose iterator/part getter throws) happens before the guarded
|
|
3040
|
+
// try below, so resolve the deferred-turn claim first to keep agent_idle reachable.
|
|
3016
3041
|
let text;
|
|
3017
3042
|
let images;
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3043
|
+
try {
|
|
3044
|
+
if (typeof content === "string") {
|
|
3045
|
+
text = content;
|
|
3046
|
+
}
|
|
3047
|
+
else {
|
|
3048
|
+
const textParts = [];
|
|
3049
|
+
images = [];
|
|
3050
|
+
for (const part of content) {
|
|
3051
|
+
if (part.type === "text") {
|
|
3052
|
+
textParts.push(part.text);
|
|
3053
|
+
}
|
|
3054
|
+
else {
|
|
3055
|
+
images.push(part);
|
|
3056
|
+
}
|
|
3030
3057
|
}
|
|
3058
|
+
text = textParts.join("\n");
|
|
3059
|
+
if (images.length === 0)
|
|
3060
|
+
images = undefined;
|
|
3031
3061
|
}
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3062
|
+
}
|
|
3063
|
+
catch (error) {
|
|
3064
|
+
deferredTurnClaim?.resolve("finished-without-start");
|
|
3065
|
+
resolveBindingPromptReadiness?.();
|
|
3066
|
+
throw error;
|
|
3035
3067
|
}
|
|
3036
3068
|
// An extension binding invokes this method fire-and-forget. When it
|
|
3037
3069
|
// arrives during session work, retain a barrier token after the prior work
|
|
@@ -3047,6 +3079,10 @@ export class AgentSession {
|
|
|
3047
3079
|
source: "extension",
|
|
3048
3080
|
promptDisposition: (nextDisposition) => {
|
|
3049
3081
|
disposition = nextDisposition;
|
|
3082
|
+
if (nextDisposition === "started")
|
|
3083
|
+
deferredTurnClaim?.resolve("started");
|
|
3084
|
+
else if (nextDisposition === "queued")
|
|
3085
|
+
deferredTurnClaim?.resolve("delegated");
|
|
3050
3086
|
resolveBindingPromptReadiness?.();
|
|
3051
3087
|
},
|
|
3052
3088
|
onSessionWorkReady: waitForExistingSessionWork
|
|
@@ -3071,6 +3107,9 @@ export class AgentSession {
|
|
|
3071
3107
|
throw error;
|
|
3072
3108
|
}
|
|
3073
3109
|
finally {
|
|
3110
|
+
// A path that neither started nor delegated a turn (handled, rejected,
|
|
3111
|
+
// admission failure, cancellation) resolves as finished-without-start.
|
|
3112
|
+
deferredTurnClaim?.resolve("finished-without-start");
|
|
3074
3113
|
resolveBindingPromptReadiness?.();
|
|
3075
3114
|
finishSessionWork?.();
|
|
3076
3115
|
}
|
|
@@ -4902,25 +4941,41 @@ export class AgentSession {
|
|
|
4902
4941
|
};
|
|
4903
4942
|
runner.bindCore({
|
|
4904
4943
|
sendMessage: (message, options) => {
|
|
4905
|
-
const
|
|
4944
|
+
const reportError = (err) => {
|
|
4906
4945
|
runner.emitError({
|
|
4907
4946
|
extensionPath: RUNTIME_EXTENSION_PATH,
|
|
4908
4947
|
event: "send_message",
|
|
4909
4948
|
error: err instanceof Error ? err.message : String(err),
|
|
4910
4949
|
});
|
|
4911
|
-
}
|
|
4950
|
+
};
|
|
4951
|
+
if (options?.triggerTurn === true) {
|
|
4952
|
+
if (this._agentSettledDelivery.deferTriggerTurn((claim) => {
|
|
4953
|
+
this.sendCustomMessage(message, options, claim).catch(reportError);
|
|
4954
|
+
})) {
|
|
4955
|
+
return;
|
|
4956
|
+
}
|
|
4957
|
+
}
|
|
4958
|
+
const send = () => this.sendCustomMessage(message, options).catch(reportError);
|
|
4912
4959
|
if (this._agentSettledDelivery.defer(send))
|
|
4913
4960
|
return;
|
|
4914
4961
|
send();
|
|
4915
4962
|
},
|
|
4916
4963
|
sendUserMessage: (content, options) => {
|
|
4917
|
-
|
|
4964
|
+
const reportError = (err) => {
|
|
4918
4965
|
runner.emitError({
|
|
4919
4966
|
extensionPath: RUNTIME_EXTENSION_PATH,
|
|
4920
4967
|
event: "send_user_message",
|
|
4921
4968
|
error: err instanceof Error ? err.message : String(err),
|
|
4922
4969
|
});
|
|
4923
|
-
}
|
|
4970
|
+
};
|
|
4971
|
+
// sendUserMessage always triggers a turn; register a settlement-deferred
|
|
4972
|
+
// turn claim so agent_idle is not emitted before its deferred agent_start.
|
|
4973
|
+
if (this._agentSettledDelivery.deferTriggerTurn((claim) => {
|
|
4974
|
+
this.sendUserMessage(content, options, claim).catch(reportError);
|
|
4975
|
+
})) {
|
|
4976
|
+
return;
|
|
4977
|
+
}
|
|
4978
|
+
this.sendUserMessage(content, options).catch(reportError);
|
|
4924
4979
|
},
|
|
4925
4980
|
appendEntry: (customType, data) => {
|
|
4926
4981
|
const entryId = this.sessionManager.appendCustomEntry(customType, data);
|