@ycodium-ai/agent-kimi 0.2.3130 → 0.2.3168
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.js +337 -107
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -24945,7 +24945,10 @@ function createAcpConnection(options) {
|
|
|
24945
24945
|
}
|
|
24946
24946
|
pending.delete(key);
|
|
24947
24947
|
try {
|
|
24948
|
-
options.onResponse?.(
|
|
24948
|
+
options.onResponse?.(
|
|
24949
|
+
waiter,
|
|
24950
|
+
Object.hasOwn(message, "error") ? { error: message["error"] } : { result: message["result"] }
|
|
24951
|
+
);
|
|
24949
24952
|
} catch {
|
|
24950
24953
|
}
|
|
24951
24954
|
if (Object.hasOwn(message, "error")) {
|
|
@@ -25078,12 +25081,17 @@ function createAcpConnection(options) {
|
|
|
25078
25081
|
options.readable.on("end", onEnd);
|
|
25079
25082
|
options.readable.on("error", onError);
|
|
25080
25083
|
options.writable.once("error", onWritableError);
|
|
25081
|
-
const begin = (method, params) => {
|
|
25084
|
+
const begin = (method, params, promptId) => {
|
|
25082
25085
|
failIfClosed();
|
|
25083
25086
|
const id = nextRequestId;
|
|
25084
25087
|
nextRequestId += 1;
|
|
25085
25088
|
const { promise: promise2, resolve: resolve3, reject } = Promise.withResolvers();
|
|
25086
|
-
pending.set(String(id), {
|
|
25089
|
+
pending.set(String(id), {
|
|
25090
|
+
method,
|
|
25091
|
+
...promptId === void 0 ? {} : { promptId },
|
|
25092
|
+
resolve: resolve3,
|
|
25093
|
+
reject
|
|
25094
|
+
});
|
|
25087
25095
|
const message = params === void 0 ? { jsonrpc: "2.0", id, method } : { jsonrpc: "2.0", id, method, params };
|
|
25088
25096
|
const written = Promise.race([writeMessage(message), promise2]).then(
|
|
25089
25097
|
() => void 0,
|
|
@@ -25153,12 +25161,14 @@ function createExecutorLifecycle({
|
|
|
25153
25161
|
notifyPromptSettled,
|
|
25154
25162
|
eventStream,
|
|
25155
25163
|
onInputDead,
|
|
25156
|
-
shared
|
|
25164
|
+
shared,
|
|
25165
|
+
promptResults
|
|
25157
25166
|
}) {
|
|
25158
25167
|
const cancel = async (turnId) => {
|
|
25159
25168
|
failIfDisposed();
|
|
25160
25169
|
const started = requireStarted();
|
|
25161
25170
|
const targetTurnId = turnId ?? shared.activeTurnId;
|
|
25171
|
+
promptResults.stop(targetTurnId);
|
|
25162
25172
|
if (targetTurnId !== void 0) {
|
|
25163
25173
|
interruptedTurnIds.add(targetTurnId);
|
|
25164
25174
|
}
|
|
@@ -25169,6 +25179,9 @@ function createExecutorLifecycle({
|
|
|
25169
25179
|
if (shared.sessionId) {
|
|
25170
25180
|
await connection.notify("session/cancel", { sessionId: shared.sessionId });
|
|
25171
25181
|
}
|
|
25182
|
+
await promptResults.wait(targetTurnId);
|
|
25183
|
+
if (targetTurnId !== void 0 && shared.activeTurnId !== targetTurnId && !interruptedTurnIds.has(targetTurnId))
|
|
25184
|
+
return;
|
|
25172
25185
|
const settled = await waitForPromptIdle(cancelGraceMs);
|
|
25173
25186
|
if (!settled) {
|
|
25174
25187
|
throw new AcpExecutorCancelTimeoutError();
|
|
@@ -25189,6 +25202,7 @@ function createExecutorLifecycle({
|
|
|
25189
25202
|
payload: { state: "cancelled", stopReason: "cancelled" }
|
|
25190
25203
|
});
|
|
25191
25204
|
interruptedTurnIds.delete(targetTurnId);
|
|
25205
|
+
promptResults.forget(targetTurnId);
|
|
25192
25206
|
}
|
|
25193
25207
|
}
|
|
25194
25208
|
}
|
|
@@ -25263,33 +25277,39 @@ function createExecutorLifecycle({
|
|
|
25263
25277
|
if (!shared.disposed) emitSessionState("ready");
|
|
25264
25278
|
}
|
|
25265
25279
|
};
|
|
25266
|
-
|
|
25267
|
-
|
|
25268
|
-
|
|
25269
|
-
|
|
25280
|
+
let disposing;
|
|
25281
|
+
const dispose = () => {
|
|
25282
|
+
if (disposing) return disposing;
|
|
25283
|
+
shared.disposing = true;
|
|
25284
|
+
promptResults.stop();
|
|
25270
25285
|
settleAllApprovals("cancel");
|
|
25271
25286
|
settleAllUserInputs();
|
|
25272
25287
|
abortPendingSettlement("executor disposed");
|
|
25273
25288
|
notifyPromptSettled();
|
|
25274
25289
|
shared.abortLocalPrompt?.();
|
|
25275
|
-
|
|
25276
|
-
|
|
25277
|
-
|
|
25278
|
-
|
|
25279
|
-
|
|
25280
|
-
|
|
25281
|
-
|
|
25282
|
-
|
|
25283
|
-
|
|
25284
|
-
|
|
25285
|
-
|
|
25286
|
-
|
|
25287
|
-
|
|
25288
|
-
|
|
25289
|
-
|
|
25290
|
-
|
|
25291
|
-
|
|
25292
|
-
|
|
25290
|
+
disposing = (async () => {
|
|
25291
|
+
promptResults.finishUnreceived();
|
|
25292
|
+
await promptResults.wait();
|
|
25293
|
+
emit({
|
|
25294
|
+
type: "session.exited",
|
|
25295
|
+
...stamp(),
|
|
25296
|
+
provider: options.provider,
|
|
25297
|
+
threadId: options.threadId,
|
|
25298
|
+
payload: { reason: "disposed" }
|
|
25299
|
+
});
|
|
25300
|
+
shared.disposed = true;
|
|
25301
|
+
shared.generation += 1;
|
|
25302
|
+
shared.status = "disposed";
|
|
25303
|
+
eventStream.close();
|
|
25304
|
+
options.readable.off("end", onInputDead);
|
|
25305
|
+
options.readable.off("error", onInputDead);
|
|
25306
|
+
options.readable.pause();
|
|
25307
|
+
if (!shared.connectionClosed) {
|
|
25308
|
+
await connection.awaitInboundIdle().catch(() => void 0);
|
|
25309
|
+
await connection.close().catch(() => void 0);
|
|
25310
|
+
}
|
|
25311
|
+
})();
|
|
25312
|
+
return disposing;
|
|
25293
25313
|
};
|
|
25294
25314
|
return { cancel, compact, dispose };
|
|
25295
25315
|
}
|
|
@@ -25393,12 +25413,14 @@ function createExecutorPrompt({
|
|
|
25393
25413
|
promptMutex,
|
|
25394
25414
|
applyRequestedModel,
|
|
25395
25415
|
notifyPromptSettled,
|
|
25396
|
-
shared
|
|
25416
|
+
shared,
|
|
25417
|
+
promptResults
|
|
25397
25418
|
}) {
|
|
25398
25419
|
const settleTurn = (input2) => {
|
|
25399
|
-
if (!isLive(input2.expectedGeneration)) {
|
|
25420
|
+
if (!isLive(input2.expectedGeneration) || input2.record.finished) {
|
|
25400
25421
|
return false;
|
|
25401
25422
|
}
|
|
25423
|
+
promptResults.complete(input2.record);
|
|
25402
25424
|
if (!acpPromptSettlementBelongsToContext({
|
|
25403
25425
|
liveAcpSessionId: shared.sessionId ?? "",
|
|
25404
25426
|
expectedAcpSessionId: input2.expectedSessionId,
|
|
@@ -25415,6 +25437,7 @@ function createExecutorPrompt({
|
|
|
25415
25437
|
if (shared.status !== "disposed") {
|
|
25416
25438
|
shared.status = "ready";
|
|
25417
25439
|
}
|
|
25440
|
+
const interrupted = promptResults.hasInterrupted(input2.turnId);
|
|
25418
25441
|
emit({
|
|
25419
25442
|
type: "turn.completed",
|
|
25420
25443
|
...stamp(),
|
|
@@ -25422,30 +25445,44 @@ function createExecutorPrompt({
|
|
|
25422
25445
|
threadId: options.threadId,
|
|
25423
25446
|
turnId: input2.turnId,
|
|
25424
25447
|
payload: {
|
|
25425
|
-
state: input2.state,
|
|
25426
|
-
stopReason: input2.stopReason,
|
|
25448
|
+
state: interrupted ? "cancelled" : input2.state,
|
|
25449
|
+
stopReason: interrupted ? "cancelled" : input2.stopReason,
|
|
25427
25450
|
...input2.errorMessage === void 0 ? {} : { errorMessage: input2.errorMessage },
|
|
25428
25451
|
...input2.state === "failed" ? failureCategoryField(input2.failureCategory) : {}
|
|
25429
25452
|
}
|
|
25430
25453
|
});
|
|
25431
25454
|
interruptedTurnIds.delete(input2.turnId);
|
|
25455
|
+
promptResults.forget(input2.turnId);
|
|
25432
25456
|
return true;
|
|
25433
25457
|
};
|
|
25434
|
-
const sendPromptRpc = async (sessionId, promptParts, onWritten) => {
|
|
25458
|
+
const sendPromptRpc = async (sessionId, promptParts, onWritten, record2) => {
|
|
25435
25459
|
const settlementHooks = hooks.promptSettlement;
|
|
25436
25460
|
const promptKey = settlementHooks === void 0 ? void 0 : randomId();
|
|
25437
|
-
const pending = connection.begin(
|
|
25438
|
-
|
|
25439
|
-
|
|
25440
|
-
|
|
25441
|
-
|
|
25461
|
+
const pending = connection.begin(
|
|
25462
|
+
"session/prompt",
|
|
25463
|
+
{
|
|
25464
|
+
sessionId,
|
|
25465
|
+
prompt: promptParts,
|
|
25466
|
+
...settlementHooks !== void 0 && promptKey !== void 0 ? settlementHooks.requestFields(promptKey) : {}
|
|
25467
|
+
},
|
|
25468
|
+
record2?.promptId
|
|
25469
|
+
);
|
|
25442
25470
|
void pending.written.then(onWritten, () => void 0);
|
|
25443
25471
|
const promptRpc = pending.response;
|
|
25444
25472
|
if (settlementHooks === void 0 || promptKey === void 0) {
|
|
25445
25473
|
return await promptRpc;
|
|
25446
25474
|
} else {
|
|
25447
25475
|
const { promise: early, resolve: settleEarly } = Promise.withResolvers();
|
|
25448
|
-
shared.pendingSettlement = {
|
|
25476
|
+
shared.pendingSettlement = {
|
|
25477
|
+
promptKey,
|
|
25478
|
+
sessionId,
|
|
25479
|
+
settle: settleEarly,
|
|
25480
|
+
...record2 === void 0 ? {} : {
|
|
25481
|
+
onResponse: (response) => promptResults.receive(record2.promptId, response),
|
|
25482
|
+
onError: () => promptResults.reject(record2.promptId),
|
|
25483
|
+
hasResult: () => record2.response !== void 0
|
|
25484
|
+
}
|
|
25485
|
+
};
|
|
25449
25486
|
try {
|
|
25450
25487
|
const outcome = await Promise.race([
|
|
25451
25488
|
promptRpc.then((value) => {
|
|
@@ -25466,9 +25503,11 @@ function createExecutorPrompt({
|
|
|
25466
25503
|
const prompt = async (input2) => {
|
|
25467
25504
|
failIfDisposed();
|
|
25468
25505
|
const started = requireStarted();
|
|
25506
|
+
let record2;
|
|
25469
25507
|
const settle2 = (rest) => settleTurn({
|
|
25470
25508
|
expectedGeneration: started.generation,
|
|
25471
25509
|
expectedSessionId: started.sessionId,
|
|
25510
|
+
record: record2,
|
|
25472
25511
|
...rest
|
|
25473
25512
|
});
|
|
25474
25513
|
let turnId;
|
|
@@ -25481,6 +25520,17 @@ function createExecutorPrompt({
|
|
|
25481
25520
|
randomId
|
|
25482
25521
|
);
|
|
25483
25522
|
shared.promptsInFlight += 1;
|
|
25523
|
+
record2 = promptResults.add(
|
|
25524
|
+
{
|
|
25525
|
+
promptId: randomId(),
|
|
25526
|
+
sessionId: started.sessionId,
|
|
25527
|
+
generation: started.generation,
|
|
25528
|
+
turnId
|
|
25529
|
+
},
|
|
25530
|
+
() => {
|
|
25531
|
+
finishPrompt();
|
|
25532
|
+
}
|
|
25533
|
+
);
|
|
25484
25534
|
shared.activeTurnId = turnId;
|
|
25485
25535
|
shared.status = "running";
|
|
25486
25536
|
if (shared.promptsInFlight === 1) {
|
|
@@ -25497,6 +25547,42 @@ function createExecutorPrompt({
|
|
|
25497
25547
|
threadMutex.release();
|
|
25498
25548
|
}
|
|
25499
25549
|
const promptParts = input2.prompt ?? (input2.text !== void 0 ? [{ type: "text", text: input2.text }] : [{ type: "text", text: "" }]);
|
|
25550
|
+
let contextWindow;
|
|
25551
|
+
const finishPrompt = () => {
|
|
25552
|
+
if (!isLive(started.generation) || record2.finished) throw new AcpExecutorDisposedError();
|
|
25553
|
+
const response2 = record2.response;
|
|
25554
|
+
if (record2.interrupted || response2 === void 0) {
|
|
25555
|
+
settle2({ turnId, stopReason: "cancelled", state: "cancelled" });
|
|
25556
|
+
return { threadId: options.threadId, turnId, stopReason: "cancelled" };
|
|
25557
|
+
}
|
|
25558
|
+
const stopReason = hooks.completedStopReason?.(response2) ?? response2.stopReason;
|
|
25559
|
+
if (contextWindow !== void 0) {
|
|
25560
|
+
emit({
|
|
25561
|
+
type: "thread.token-usage.updated",
|
|
25562
|
+
...stamp(),
|
|
25563
|
+
provider: options.provider,
|
|
25564
|
+
threadId: options.threadId,
|
|
25565
|
+
turnId,
|
|
25566
|
+
payload: {
|
|
25567
|
+
usage: {
|
|
25568
|
+
usedTokens: contextWindow.usedTokens,
|
|
25569
|
+
...contextWindow.maxTokens === void 0 ? {} : { maxTokens: contextWindow.maxTokens }
|
|
25570
|
+
}
|
|
25571
|
+
}
|
|
25572
|
+
});
|
|
25573
|
+
}
|
|
25574
|
+
settle2({
|
|
25575
|
+
turnId,
|
|
25576
|
+
stopReason,
|
|
25577
|
+
state: response2.stopReason === "cancelled" ? "cancelled" : "completed"
|
|
25578
|
+
});
|
|
25579
|
+
return {
|
|
25580
|
+
threadId: options.threadId,
|
|
25581
|
+
turnId,
|
|
25582
|
+
stopReason,
|
|
25583
|
+
...response2.usage !== void 0 && response2.usage !== null ? { usage: response2.usage } : {}
|
|
25584
|
+
};
|
|
25585
|
+
};
|
|
25500
25586
|
await promptMutex.acquire();
|
|
25501
25587
|
let response;
|
|
25502
25588
|
try {
|
|
@@ -25511,6 +25597,7 @@ function createExecutorPrompt({
|
|
|
25511
25597
|
expectedGeneration: started.generation
|
|
25512
25598
|
});
|
|
25513
25599
|
}
|
|
25600
|
+
failIfDisposed();
|
|
25514
25601
|
if (isStale()) {
|
|
25515
25602
|
settle2({ turnId, stopReason: "cancelled", state: "cancelled" });
|
|
25516
25603
|
return { threadId: options.threadId, turnId, stopReason: "cancelled" };
|
|
@@ -25518,10 +25605,15 @@ function createExecutorPrompt({
|
|
|
25518
25605
|
closeActiveAssistantSegment(turnId);
|
|
25519
25606
|
let written = false;
|
|
25520
25607
|
try {
|
|
25521
|
-
response = await sendPromptRpc(
|
|
25522
|
-
|
|
25523
|
-
|
|
25524
|
-
|
|
25608
|
+
response = await sendPromptRpc(
|
|
25609
|
+
started.sessionId,
|
|
25610
|
+
promptParts,
|
|
25611
|
+
() => {
|
|
25612
|
+
written = true;
|
|
25613
|
+
input2.onDispatched?.(turnId);
|
|
25614
|
+
},
|
|
25615
|
+
record2
|
|
25616
|
+
);
|
|
25525
25617
|
} catch (error62) {
|
|
25526
25618
|
if (shared.disposed) {
|
|
25527
25619
|
throw new AcpExecutorDisposedError();
|
|
@@ -25560,8 +25652,7 @@ function createExecutorPrompt({
|
|
|
25560
25652
|
if (turnId === void 0) {
|
|
25561
25653
|
throw new AcpExecutorError("internal", "ACP prompt settled without a turn id");
|
|
25562
25654
|
}
|
|
25563
|
-
|
|
25564
|
-
let contextWindow;
|
|
25655
|
+
if (record2.finished) throw new AcpExecutorDisposedError();
|
|
25565
25656
|
if (hooks.readContextWindow !== void 0) {
|
|
25566
25657
|
try {
|
|
25567
25658
|
contextWindow = await hooks.readContextWindow({
|
|
@@ -25572,43 +25663,6 @@ function createExecutorPrompt({
|
|
|
25572
25663
|
contextWindow = void 0;
|
|
25573
25664
|
}
|
|
25574
25665
|
}
|
|
25575
|
-
const finishPrompt = () => {
|
|
25576
|
-
if (interruptedTurnIds.has(settledTurnId)) {
|
|
25577
|
-
settle2({ turnId: settledTurnId, stopReason: "cancelled", state: "cancelled" });
|
|
25578
|
-
return {
|
|
25579
|
-
threadId: options.threadId,
|
|
25580
|
-
turnId: settledTurnId,
|
|
25581
|
-
stopReason: "cancelled"
|
|
25582
|
-
};
|
|
25583
|
-
}
|
|
25584
|
-
const stopReason = hooks.completedStopReason?.(response) ?? response.stopReason;
|
|
25585
|
-
if (contextWindow !== void 0) {
|
|
25586
|
-
emit({
|
|
25587
|
-
type: "thread.token-usage.updated",
|
|
25588
|
-
...stamp(),
|
|
25589
|
-
provider: options.provider,
|
|
25590
|
-
threadId: options.threadId,
|
|
25591
|
-
turnId: settledTurnId,
|
|
25592
|
-
payload: {
|
|
25593
|
-
usage: {
|
|
25594
|
-
usedTokens: contextWindow.usedTokens,
|
|
25595
|
-
...contextWindow.maxTokens === void 0 ? {} : { maxTokens: contextWindow.maxTokens }
|
|
25596
|
-
}
|
|
25597
|
-
}
|
|
25598
|
-
});
|
|
25599
|
-
}
|
|
25600
|
-
settle2({
|
|
25601
|
-
turnId: settledTurnId,
|
|
25602
|
-
stopReason,
|
|
25603
|
-
state: response.stopReason === "cancelled" ? "cancelled" : "completed"
|
|
25604
|
-
});
|
|
25605
|
-
return {
|
|
25606
|
-
threadId: options.threadId,
|
|
25607
|
-
turnId: settledTurnId,
|
|
25608
|
-
stopReason,
|
|
25609
|
-
...response.usage !== void 0 && response.usage !== null ? { usage: response.usage } : {}
|
|
25610
|
-
};
|
|
25611
|
-
};
|
|
25612
25666
|
if (threadMutex.tryAcquire()) {
|
|
25613
25667
|
try {
|
|
25614
25668
|
return finishPrompt();
|
|
@@ -25626,6 +25680,91 @@ function createExecutorPrompt({
|
|
|
25626
25680
|
return { sendPromptRpc, prompt };
|
|
25627
25681
|
}
|
|
25628
25682
|
|
|
25683
|
+
// ../../packages/ycodium-acp-executor/src/executor/prompt-results.ts
|
|
25684
|
+
function createPromptResults({
|
|
25685
|
+
options,
|
|
25686
|
+
shared
|
|
25687
|
+
}) {
|
|
25688
|
+
const prompts = /* @__PURE__ */ new Map();
|
|
25689
|
+
const add = (identity, finish) => {
|
|
25690
|
+
const { promise: done, resolve: resolve3 } = Promise.withResolvers();
|
|
25691
|
+
const record2 = {
|
|
25692
|
+
...identity,
|
|
25693
|
+
finish,
|
|
25694
|
+
done,
|
|
25695
|
+
resolve: resolve3,
|
|
25696
|
+
rejected: false,
|
|
25697
|
+
interrupted: false,
|
|
25698
|
+
finished: false
|
|
25699
|
+
};
|
|
25700
|
+
prompts.set(record2.promptId, record2);
|
|
25701
|
+
return record2;
|
|
25702
|
+
};
|
|
25703
|
+
const receive = (promptId, response) => {
|
|
25704
|
+
const record2 = prompts.get(promptId);
|
|
25705
|
+
if (!record2 || record2.finished || record2.rejected || record2.response !== void 0) return;
|
|
25706
|
+
if (shared.disposed || shared.generation !== record2.generation || shared.sessionId !== record2.sessionId)
|
|
25707
|
+
return;
|
|
25708
|
+
record2.response = response;
|
|
25709
|
+
};
|
|
25710
|
+
const reject = (promptId) => {
|
|
25711
|
+
const record2 = prompts.get(promptId);
|
|
25712
|
+
if (record2 && record2.response === void 0) record2.rejected = true;
|
|
25713
|
+
};
|
|
25714
|
+
const stop = (turnId) => {
|
|
25715
|
+
for (const record2 of prompts.values()) {
|
|
25716
|
+
if (!record2.finished && (turnId === void 0 || record2.turnId === turnId) && record2.response === void 0) {
|
|
25717
|
+
record2.interrupted = true;
|
|
25718
|
+
}
|
|
25719
|
+
}
|
|
25720
|
+
};
|
|
25721
|
+
const complete = (record2) => {
|
|
25722
|
+
record2.finished = true;
|
|
25723
|
+
record2.resolve();
|
|
25724
|
+
};
|
|
25725
|
+
const hasInterrupted = (turnId) => [...prompts.values()].some((record2) => record2.turnId === turnId && record2.interrupted);
|
|
25726
|
+
const forget = (turnId) => {
|
|
25727
|
+
for (const [id, record2] of prompts) {
|
|
25728
|
+
if (record2.turnId === turnId) {
|
|
25729
|
+
complete(record2);
|
|
25730
|
+
prompts.delete(id);
|
|
25731
|
+
}
|
|
25732
|
+
}
|
|
25733
|
+
};
|
|
25734
|
+
const wait = async (turnId) => {
|
|
25735
|
+
const claimed = [...prompts.values()].filter(
|
|
25736
|
+
(record2) => !record2.finished && record2.response !== void 0 && (turnId === void 0 || record2.turnId === turnId)
|
|
25737
|
+
);
|
|
25738
|
+
if (claimed.length === 0) return;
|
|
25739
|
+
let timer;
|
|
25740
|
+
try {
|
|
25741
|
+
const drained = await Promise.race([
|
|
25742
|
+
Promise.all(claimed.map((record2) => record2.done)).then(() => true),
|
|
25743
|
+
new Promise((resolve3) => {
|
|
25744
|
+
timer = setTimeout(() => resolve3(false), options.resultDrainTimeoutMs ?? 2e3);
|
|
25745
|
+
})
|
|
25746
|
+
]);
|
|
25747
|
+
if (drained) return;
|
|
25748
|
+
options.log?.warn?.("ACP result settlement timed out", { threadId: options.threadId });
|
|
25749
|
+
for (const record2 of claimed) if (!record2.finished) record2.finish();
|
|
25750
|
+
} finally {
|
|
25751
|
+
clearTimeout(timer);
|
|
25752
|
+
}
|
|
25753
|
+
};
|
|
25754
|
+
const finishUnreceived = () => {
|
|
25755
|
+
const claimedTurns = new Set(
|
|
25756
|
+
[...prompts.values()].filter((record2) => !record2.finished && record2.response !== void 0).map((record2) => record2.turnId)
|
|
25757
|
+
);
|
|
25758
|
+
for (const record2 of prompts.values()) {
|
|
25759
|
+
if (!record2.finished && record2.response === void 0) {
|
|
25760
|
+
if (claimedTurns.has(record2.turnId)) record2.finish();
|
|
25761
|
+
else complete(record2);
|
|
25762
|
+
}
|
|
25763
|
+
}
|
|
25764
|
+
};
|
|
25765
|
+
return { add, receive, reject, stop, complete, hasInterrupted, forget, wait, finishUnreceived };
|
|
25766
|
+
}
|
|
25767
|
+
|
|
25629
25768
|
// ../../packages/ycodium-acp-executor/src/user-input-pending.ts
|
|
25630
25769
|
var userInputAnswerOptionId = (question, answers) => {
|
|
25631
25770
|
const answer = answers[question.id];
|
|
@@ -25932,7 +26071,7 @@ function createExecutorRuntime({
|
|
|
25932
26071
|
turnId: () => shared.activeTurnId
|
|
25933
26072
|
});
|
|
25934
26073
|
const failIfDisposed = () => {
|
|
25935
|
-
if (shared.disposed) {
|
|
26074
|
+
if (shared.disposed || shared.disposing) {
|
|
25936
26075
|
throw new AcpExecutorDisposedError();
|
|
25937
26076
|
}
|
|
25938
26077
|
};
|
|
@@ -26457,6 +26596,7 @@ function createExecutorSettlement({
|
|
|
26457
26596
|
const abortPendingSettlement = (reason, failureCategory) => {
|
|
26458
26597
|
const waiting = shared.pendingSettlement;
|
|
26459
26598
|
if (waiting === void 0) return;
|
|
26599
|
+
if (waiting.hasResult?.()) return;
|
|
26460
26600
|
shared.pendingSettlement = void 0;
|
|
26461
26601
|
waiting.settle({
|
|
26462
26602
|
error: withFailureCategory(
|
|
@@ -26478,6 +26618,7 @@ function createExecutorSettlement({
|
|
|
26478
26618
|
shared.pendingSettlement = void 0;
|
|
26479
26619
|
rememberSettledPromptKey(waiting.promptKey);
|
|
26480
26620
|
if (signal.outcome === "error") {
|
|
26621
|
+
waiting.onError?.();
|
|
26481
26622
|
waiting.settle({
|
|
26482
26623
|
error: withFailureCategory(
|
|
26483
26624
|
new AcpExecutorRequestError(
|
|
@@ -26488,8 +26629,10 @@ function createExecutorSettlement({
|
|
|
26488
26629
|
)
|
|
26489
26630
|
});
|
|
26490
26631
|
} else {
|
|
26632
|
+
const response = { stopReason: signal.stopReason ?? "end_turn" };
|
|
26633
|
+
waiting.onResponse?.(response);
|
|
26491
26634
|
waiting.settle({
|
|
26492
|
-
response
|
|
26635
|
+
response
|
|
26493
26636
|
});
|
|
26494
26637
|
}
|
|
26495
26638
|
return true;
|
|
@@ -26819,6 +26962,7 @@ function createAcpExecutor(options) {
|
|
|
26819
26962
|
const shared = {
|
|
26820
26963
|
generation: 0,
|
|
26821
26964
|
disposed: false,
|
|
26965
|
+
disposing: false,
|
|
26822
26966
|
status: "idle",
|
|
26823
26967
|
sessionId: void 0,
|
|
26824
26968
|
modelSelectionState: {
|
|
@@ -26906,6 +27050,7 @@ function createAcpExecutor(options) {
|
|
|
26906
27050
|
shared
|
|
26907
27051
|
});
|
|
26908
27052
|
const { rememberSettledPromptKey, abortPendingSettlement, settleFromNotification } = createExecutorSettlement({ hooks, shared });
|
|
27053
|
+
const promptResults = createPromptResults({ options, shared });
|
|
26909
27054
|
const connection = createAcpConnection({
|
|
26910
27055
|
readable: options.readable,
|
|
26911
27056
|
writable: options.writable,
|
|
@@ -26916,8 +27061,12 @@ function createAcpExecutor(options) {
|
|
|
26916
27061
|
});
|
|
26917
27062
|
},
|
|
26918
27063
|
// 窗口在应答帧到达的那一刻同步收掉:应答之后的通知是真输出,不能再丢。
|
|
26919
|
-
onResponse: (method) => {
|
|
27064
|
+
onResponse: ({ method, promptId }, outcome) => {
|
|
26920
27065
|
if (method === "session/load") shared.sessionLoadInFlight = false;
|
|
27066
|
+
if (promptId !== void 0) {
|
|
27067
|
+
if ("result" in outcome) promptResults.receive(promptId, outcome.result);
|
|
27068
|
+
else promptResults.reject(promptId);
|
|
27069
|
+
}
|
|
26921
27070
|
},
|
|
26922
27071
|
onNotification: (notification) => {
|
|
26923
27072
|
if (notification.method === "session/update") {
|
|
@@ -26982,6 +27131,7 @@ function createAcpExecutor(options) {
|
|
|
26982
27131
|
shared
|
|
26983
27132
|
});
|
|
26984
27133
|
const { sendPromptRpc, prompt } = createExecutorPrompt({
|
|
27134
|
+
promptResults,
|
|
26985
27135
|
isLive,
|
|
26986
27136
|
closeActiveAssistantSegment,
|
|
26987
27137
|
emit,
|
|
@@ -27001,6 +27151,7 @@ function createAcpExecutor(options) {
|
|
|
27001
27151
|
shared
|
|
27002
27152
|
});
|
|
27003
27153
|
const { cancel, compact, dispose } = createExecutorLifecycle({
|
|
27154
|
+
promptResults,
|
|
27004
27155
|
failIfDisposed,
|
|
27005
27156
|
requireStarted,
|
|
27006
27157
|
interruptedTurnIds,
|
|
@@ -27052,6 +27203,41 @@ function createAcpExecutor(options) {
|
|
|
27052
27203
|
};
|
|
27053
27204
|
}
|
|
27054
27205
|
|
|
27206
|
+
// ../../packages/ycodium-acp-executor/src/session-registry.ts
|
|
27207
|
+
function createAcpSessionRegistry(threads, stopBooked2) {
|
|
27208
|
+
const requireThread = (threadId) => {
|
|
27209
|
+
const booked = threads.get(threadId);
|
|
27210
|
+
if (!booked) throw new Error(`unknown thread ${threadId}`);
|
|
27211
|
+
if (booked.closing) throw new Error(`thread ${threadId} is closing`);
|
|
27212
|
+
return booked;
|
|
27213
|
+
};
|
|
27214
|
+
const stopSession = (threadId, booked = threads.get(threadId)) => {
|
|
27215
|
+
if (!booked) return Promise.resolve();
|
|
27216
|
+
booked.closing ??= Promise.resolve().then(() => stopBooked2(booked)).then(() => {
|
|
27217
|
+
if (threads.get(threadId) === booked) threads.delete(threadId);
|
|
27218
|
+
});
|
|
27219
|
+
return booked.closing;
|
|
27220
|
+
};
|
|
27221
|
+
const stopAll = () => Promise.all([...threads].map(([threadId, booked]) => stopSession(threadId, booked))).then(
|
|
27222
|
+
() => void 0
|
|
27223
|
+
);
|
|
27224
|
+
return { requireThread, stopSession, stopAll };
|
|
27225
|
+
}
|
|
27226
|
+
|
|
27227
|
+
// ../../packages/ycodium-acp-executor/src/sessionProcess.ts
|
|
27228
|
+
var fileName = (path) => path.slice(path.lastIndexOf("/") + 1);
|
|
27229
|
+
var withoutExe = (name) => name.replace(/\.exe$/, "");
|
|
27230
|
+
function acpNativeSessionProcessMatcher(program, args) {
|
|
27231
|
+
return (argv, platform) => {
|
|
27232
|
+
const normalize = (value) => platform === "win32" ? withoutExe(value.replaceAll("\\", "/").toLowerCase()) : value;
|
|
27233
|
+
const expected = normalize(program);
|
|
27234
|
+
const actual = normalize(argv[0] ?? "");
|
|
27235
|
+
const sameProgram = expected.includes("/") ? actual === expected : fileName(actual) === fileName(expected);
|
|
27236
|
+
const rest = argv.slice(1);
|
|
27237
|
+
return sameProgram && rest.length === args.length && rest.every((arg, i) => arg === args[i]);
|
|
27238
|
+
};
|
|
27239
|
+
}
|
|
27240
|
+
|
|
27055
27241
|
// ../../packages/ycodium-acp-executor/src/prompt-dispatch.ts
|
|
27056
27242
|
var dispatchAcpPrompt = (executor, input2) => {
|
|
27057
27243
|
const { promise: dispatched, resolve: resolve3 } = Promise.withResolvers();
|
|
@@ -27967,6 +28153,44 @@ async function probeKimi(input2) {
|
|
|
27967
28153
|
}
|
|
27968
28154
|
}
|
|
27969
28155
|
|
|
28156
|
+
// src/openCommands.ts
|
|
28157
|
+
var basename = (path) => path.split(/[\\/]/).at(-1)?.toLowerCase() ?? "";
|
|
28158
|
+
var gitBashPath = (path) => path.replace(/^([A-Za-z]):[\\/]?/, (_match, drive) => `/${drive.toLowerCase()}/`).replaceAll("\\", "/").replace(/\/+$/, "");
|
|
28159
|
+
function kimiCommandMatcher(input2) {
|
|
28160
|
+
return (argv, platform) => {
|
|
28161
|
+
if (platform !== "win32" || input2.cwd.includes("'")) return false;
|
|
28162
|
+
return argv.length === 3 && basename(argv[0] ?? "") === "bash.exe" && argv[1] === "-c" && argv[2] === `cd '${gitBashPath(input2.cwd)}' && ${input2.command}`;
|
|
28163
|
+
};
|
|
28164
|
+
}
|
|
28165
|
+
var commandOf = (call) => {
|
|
28166
|
+
if (call.kind !== "execute") return void 0;
|
|
28167
|
+
const rawInput = call.rawInput;
|
|
28168
|
+
if (typeof rawInput !== "object" || rawInput === null) return void 0;
|
|
28169
|
+
const input2 = rawInput;
|
|
28170
|
+
if (input2["run_in_background"] === true) return void 0;
|
|
28171
|
+
const command = input2["command"];
|
|
28172
|
+
return typeof command === "string" && command.trim() !== "" ? command : void 0;
|
|
28173
|
+
};
|
|
28174
|
+
function kimiOpenCommands(session) {
|
|
28175
|
+
const commands = session.openToolCalls.flatMap((call) => {
|
|
28176
|
+
const command = commandOf(call);
|
|
28177
|
+
if (command === void 0) return [];
|
|
28178
|
+
return [
|
|
28179
|
+
{
|
|
28180
|
+
toolCallId: call.toolCallId,
|
|
28181
|
+
startedAtMs: call.startedAtMs,
|
|
28182
|
+
matches: kimiCommandMatcher({ command, cwd: session.cwd })
|
|
28183
|
+
}
|
|
28184
|
+
];
|
|
28185
|
+
});
|
|
28186
|
+
if (commands.length === 0) return void 0;
|
|
28187
|
+
return {
|
|
28188
|
+
rootPid: session.rootPid,
|
|
28189
|
+
sessionProcess: acpNativeSessionProcessMatcher(session.program, session.args),
|
|
28190
|
+
commands
|
|
28191
|
+
};
|
|
28192
|
+
}
|
|
28193
|
+
|
|
27970
28194
|
// src/runtimeModeApproval.ts
|
|
27971
28195
|
function acpRuntimeModeAutoApproves(runtimeMode, toolKind) {
|
|
27972
28196
|
switch (runtimeMode) {
|
|
@@ -28078,12 +28302,9 @@ var createKimiInstance = (config2, host) => {
|
|
|
28078
28302
|
const events = new EventBus();
|
|
28079
28303
|
const threads = /* @__PURE__ */ new Map();
|
|
28080
28304
|
let disposed = false;
|
|
28305
|
+
let disposeTask;
|
|
28081
28306
|
const usageHome = kimiEffectiveHome(resolveHomePath(recipe), process.env[recipe.homeEnvVar]);
|
|
28082
|
-
const requireThread = (
|
|
28083
|
-
const booked = threads.get(threadId);
|
|
28084
|
-
if (!booked) throw new Error(`unknown thread ${threadId}`);
|
|
28085
|
-
return booked;
|
|
28086
|
-
};
|
|
28307
|
+
const { requireThread, stopSession, stopAll } = createAcpSessionRegistry(threads, stopBooked);
|
|
28087
28308
|
const instance = {
|
|
28088
28309
|
probe: async () => {
|
|
28089
28310
|
if (recipe.binaryPath.length === 0) {
|
|
@@ -28158,15 +28379,18 @@ var createKimiInstance = (config2, host) => {
|
|
|
28158
28379
|
if (cwd.trim() === "") throw new Error("workspace path missing");
|
|
28159
28380
|
const existing = threads.get(input2.threadId);
|
|
28160
28381
|
if (existing !== void 0) {
|
|
28161
|
-
await
|
|
28162
|
-
|
|
28382
|
+
await stopSession(input2.threadId, existing);
|
|
28383
|
+
if (disposed) throw new Error("instance disposed");
|
|
28163
28384
|
throwIfStartAborted(signal);
|
|
28164
28385
|
}
|
|
28165
28386
|
const env = buildSpawnEnv(recipe, recipe.homePath);
|
|
28166
|
-
const
|
|
28387
|
+
const spawned = {
|
|
28167
28388
|
program: recipe.binaryPath,
|
|
28168
28389
|
args: tokenizeLaunchArgs(recipe.launchArgs),
|
|
28169
|
-
cwd
|
|
28390
|
+
cwd
|
|
28391
|
+
};
|
|
28392
|
+
const handle = await host.process.spawn({
|
|
28393
|
+
...spawned,
|
|
28170
28394
|
owner: { bindingId: host.bindingId },
|
|
28171
28395
|
...Object.keys(env).length > 0 ? { env } : {}
|
|
28172
28396
|
});
|
|
@@ -28252,7 +28476,8 @@ var createKimiInstance = (config2, host) => {
|
|
|
28252
28476
|
turns: [],
|
|
28253
28477
|
executor,
|
|
28254
28478
|
handle,
|
|
28255
|
-
forwarding
|
|
28479
|
+
forwarding,
|
|
28480
|
+
spawned
|
|
28256
28481
|
});
|
|
28257
28482
|
host.log.info("session started", {
|
|
28258
28483
|
threadId: input2.threadId,
|
|
@@ -28293,11 +28518,20 @@ var createKimiInstance = (config2, host) => {
|
|
|
28293
28518
|
},
|
|
28294
28519
|
interruptTurn: async (threadId, turnId) => {
|
|
28295
28520
|
const booked = threads.get(threadId);
|
|
28296
|
-
if (booked === void 0) return;
|
|
28521
|
+
if (booked === void 0 || booked.closing) return;
|
|
28297
28522
|
host.log.info("interrupt turn", { threadId, turnId });
|
|
28298
28523
|
await booked.executor.cancel(turnId);
|
|
28299
28524
|
await yieldTick();
|
|
28300
28525
|
},
|
|
28526
|
+
openCommandProcesses: async (threadId) => {
|
|
28527
|
+
const booked = threads.get(threadId);
|
|
28528
|
+
if (booked === void 0) return void 0;
|
|
28529
|
+
return kimiOpenCommands({
|
|
28530
|
+
rootPid: booked.handle.pid,
|
|
28531
|
+
...booked.spawned,
|
|
28532
|
+
openToolCalls: booked.executor.openToolCalls()
|
|
28533
|
+
});
|
|
28534
|
+
},
|
|
28301
28535
|
respondToRequest: async (threadId, requestId, decision, reason) => {
|
|
28302
28536
|
const booked = requireThread(threadId);
|
|
28303
28537
|
await booked.executor.respondToRequest(
|
|
@@ -28334,12 +28568,7 @@ var createKimiInstance = (config2, host) => {
|
|
|
28334
28568
|
updatedAt: nowIso()
|
|
28335
28569
|
};
|
|
28336
28570
|
},
|
|
28337
|
-
stopSession:
|
|
28338
|
-
const booked = threads.get(threadId);
|
|
28339
|
-
if (booked === void 0) return;
|
|
28340
|
-
threads.delete(threadId);
|
|
28341
|
-
await stopBooked(booked);
|
|
28342
|
-
},
|
|
28571
|
+
stopSession: (threadId) => stopSession(threadId),
|
|
28343
28572
|
readThread: async (threadId) => {
|
|
28344
28573
|
const booked = requireThread(threadId);
|
|
28345
28574
|
return { threadId, turns: booked.turns };
|
|
@@ -28355,13 +28584,14 @@ var createKimiInstance = (config2, host) => {
|
|
|
28355
28584
|
...createKimiTokenReader({ homePath: usageHome })
|
|
28356
28585
|
},
|
|
28357
28586
|
continuationKey: kimiContinuationKey(recipe),
|
|
28358
|
-
dispose:
|
|
28359
|
-
if (
|
|
28587
|
+
dispose: () => {
|
|
28588
|
+
if (disposeTask) return disposeTask;
|
|
28360
28589
|
disposed = true;
|
|
28361
|
-
|
|
28362
|
-
|
|
28363
|
-
|
|
28364
|
-
|
|
28590
|
+
disposeTask = (async () => {
|
|
28591
|
+
await stopAll();
|
|
28592
|
+
events.close();
|
|
28593
|
+
})();
|
|
28594
|
+
return disposeTask;
|
|
28365
28595
|
}
|
|
28366
28596
|
};
|
|
28367
28597
|
return instance;
|
|
@@ -28379,7 +28609,7 @@ var executors = [
|
|
|
28379
28609
|
];
|
|
28380
28610
|
var index_default = definePlugin({
|
|
28381
28611
|
id: "agent-kimi",
|
|
28382
|
-
apiVersion:
|
|
28612
|
+
apiVersion: 16,
|
|
28383
28613
|
executors,
|
|
28384
28614
|
activate(ctx) {
|
|
28385
28615
|
ctx.log.info("Kimi Code executor ready");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ycodium-ai/agent-kimi",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3168",
|
|
4
4
|
"description": "Kimi Code executor: runs `kimi acp` over Agent Client Protocol stdio.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ycodium",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"@types/node": "24.12.4",
|
|
22
22
|
"esbuild": "0.28.1",
|
|
23
23
|
"vite-plus": "0.2.2",
|
|
24
|
-
"@ycodium-ai/plugin-api": "0.2.
|
|
25
|
-
"ycodium-acp-executor": "0.2.
|
|
24
|
+
"@ycodium-ai/plugin-api": "0.2.3168",
|
|
25
|
+
"ycodium-acp-executor": "0.2.3168",
|
|
26
26
|
"ycodium-executor-testing": "0.0.0"
|
|
27
27
|
},
|
|
28
28
|
"ycodium": {
|