@sema-agent/client-core 0.83.4 → 0.83.5
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 +97 -0
- package/README.md +16 -15
- package/dist/adapter/activeRunSelfHeal.d.ts +3 -0
- package/dist/adapter/activeRunSelfHeal.js +39 -12
- package/dist/compensations.js +1 -1
- package/dist/displayUntrusted.d.ts +13 -0
- package/dist/displayUntrusted.js +751 -125
- package/dist/hooksWireCaps.js +78 -8
- package/dist/host.d.ts +2 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/pluginHooksWire.d.ts +9 -0
- package/dist/pluginHooksWire.js +119 -0
- package/dist/request/taskRequest.js +1 -1
- package/docs/INTEGRATION-CLIENTS.md +280 -66
- package/package.json +1 -1
|
@@ -112,6 +112,7 @@ export type SelfHealOutcome = {
|
|
|
112
112
|
kind: 'ask-decided-without-card';
|
|
113
113
|
taskId: string;
|
|
114
114
|
released: true;
|
|
115
|
+
releaseConfirmedByEngine?: true;
|
|
115
116
|
} | {
|
|
116
117
|
kind: 'ask-decided-release-unknown';
|
|
117
118
|
taskId: string;
|
|
@@ -130,6 +131,7 @@ export type SelfHealOutcome = {
|
|
|
130
131
|
} | {
|
|
131
132
|
kind: 'running-cancelled';
|
|
132
133
|
taskId: string;
|
|
134
|
+
releaseConfirmedByEngine?: true;
|
|
133
135
|
} | {
|
|
134
136
|
kind: 'running-cancel-timeout';
|
|
135
137
|
taskId: string;
|
|
@@ -147,6 +149,7 @@ export type SelfHealOutcome = {
|
|
|
147
149
|
} | {
|
|
148
150
|
kind: 'stale-park-cancelled';
|
|
149
151
|
taskId: string;
|
|
152
|
+
releaseConfirmedByEngine?: true;
|
|
150
153
|
} | {
|
|
151
154
|
kind: 'stale-park-cancel-timeout';
|
|
152
155
|
taskId: string;
|
|
@@ -341,8 +341,14 @@ async function askParkArm(taskId, signal, runs, deps) {
|
|
|
341
341
|
...(deps?.signal !== undefined ? { signal: deps.signal } : {}),
|
|
342
342
|
...sessionOpts(deps),
|
|
343
343
|
});
|
|
344
|
-
if (release.released)
|
|
345
|
-
return {
|
|
344
|
+
if (release.released) {
|
|
345
|
+
return {
|
|
346
|
+
kind: 'ask-decided-without-card',
|
|
347
|
+
taskId,
|
|
348
|
+
released: true,
|
|
349
|
+
...(release.lastHolder === 'released' ? { releaseConfirmedByEngine: true } : {}),
|
|
350
|
+
};
|
|
351
|
+
}
|
|
346
352
|
if (release.lastStatus !== null && RUNNING_STATES.includes(release.lastStatus)) {
|
|
347
353
|
return runningChoiceArm(taskId, release.lastStatus, signal, false, runs, deps);
|
|
348
354
|
}
|
|
@@ -447,8 +453,9 @@ async function staleParkArm(taskId, busy, runs, deps) {
|
|
|
447
453
|
if (stillGone !== 0)
|
|
448
454
|
return reopenFailedAfterCard;
|
|
449
455
|
const verdict = await cancelAndConfirmRelease(taskId, runs, durableGet, deps);
|
|
450
|
-
if (verdict.outcome === 'released')
|
|
451
|
-
return { kind: 'stale-park-cancelled', taskId };
|
|
456
|
+
if (verdict.outcome === 'released') {
|
|
457
|
+
return { kind: 'stale-park-cancelled', taskId, ...(verdict.engineStatedRelease ? { releaseConfirmedByEngine: true } : {}) };
|
|
458
|
+
}
|
|
452
459
|
if (verdict.outcome === 'failed') {
|
|
453
460
|
return { kind: 'stale-park-cancel-failed', taskId, detail: verdict.detail, delivery: verdict.delivery };
|
|
454
461
|
}
|
|
@@ -488,7 +495,7 @@ async function cancelAndConfirmRelease(taskId, durable, durableGet, deps) {
|
|
|
488
495
|
...sessionOpts(deps),
|
|
489
496
|
});
|
|
490
497
|
if (verdict.released)
|
|
491
|
-
return { outcome: 'released' };
|
|
498
|
+
return { outcome: 'released', engineStatedRelease: verdict.lastHolder === 'released' };
|
|
492
499
|
if (cancelFailure !== null)
|
|
493
500
|
return { outcome: 'failed', ...cancelFailure };
|
|
494
501
|
return {
|
|
@@ -580,8 +587,9 @@ async function runningChoiceArm(taskId, status, busy, statusFromWire, runs, deps
|
|
|
580
587
|
}
|
|
581
588
|
if (choice === 'cancel' && canCancel && runs?.cancel !== undefined && runs.get !== undefined) {
|
|
582
589
|
const verdict = await cancelAndConfirmRelease(taskId, runs, runs.get, deps);
|
|
583
|
-
if (verdict.outcome === 'released')
|
|
584
|
-
return { kind: 'running-cancelled', taskId };
|
|
590
|
+
if (verdict.outcome === 'released') {
|
|
591
|
+
return { kind: 'running-cancelled', taskId, ...(verdict.engineStatedRelease ? { releaseConfirmedByEngine: true } : {}) };
|
|
592
|
+
}
|
|
585
593
|
if (verdict.outcome === 'failed') {
|
|
586
594
|
return { kind: 'running-cancel-failed', taskId, detail: verdict.detail, delivery: verdict.delivery };
|
|
587
595
|
}
|
|
@@ -690,8 +698,12 @@ function injectedSubmissionRow(outcome, following = false) {
|
|
|
690
698
|
return (`${lead} is on hold: this session is busy with an earlier reply${id} that is waiting on a decision. ` +
|
|
691
699
|
`sema kept the message queued and will send it after you answer the open card.`);
|
|
692
700
|
case 'resending':
|
|
693
|
-
return
|
|
694
|
-
|
|
701
|
+
return 'releaseConfirmedByEngine' in outcome && outcome.releaseConfirmedByEngine === true
|
|
702
|
+
? `${lead} was held back because this session was busy with an earlier reply${id}; the session is free again, ` +
|
|
703
|
+
`so sema is sending the message now — nothing for you to do.`
|
|
704
|
+
: `${lead} was held back because this session was busy with an earlier reply${id}; that reply is now reported ` +
|
|
705
|
+
`as finished, so sema is sending the message now — nothing for you to do (if the session has not quite ` +
|
|
706
|
+
`freed up yet, it may be held back once more).`;
|
|
695
707
|
case 'handed-off':
|
|
696
708
|
return following
|
|
697
709
|
? `${lead} was passed to the reply already in progress${id} instead of starting a new one. ` +
|
|
@@ -749,8 +761,14 @@ function activeRunSelfHealBaseRow(outcome, signal, wayOut, following = false, ke
|
|
|
749
761
|
`reopened it. Answer it and send your message again. (sema did NOT cancel the run: cancelling ` +
|
|
750
762
|
`would have thrown the plan away on your behalf.)`);
|
|
751
763
|
case 'ask-decided-without-card':
|
|
764
|
+
if (outcome.releaseConfirmedByEngine === true) {
|
|
765
|
+
return (`The previous turn was parked on an approval that your permission rules decided on their own (no card was ` +
|
|
766
|
+
`needed); run ${outcome.taskId} resumed and the engine confirmed it is no longer holding this session — ` +
|
|
767
|
+
`sema is re-sending your message.`);
|
|
768
|
+
}
|
|
752
769
|
return (`The previous turn was parked on an approval that your permission rules decided on their own (no card was ` +
|
|
753
|
-
`needed); run ${outcome.taskId} resumed and has since finished — sema is re-sending your message
|
|
770
|
+
`needed); run ${outcome.taskId} resumed and has since finished — sema is re-sending your message; if that ` +
|
|
771
|
+
`run has not fully let go of the session yet, you may have to send it once more.`);
|
|
754
772
|
case 'ask-decided-release-unknown':
|
|
755
773
|
return (`The previous turn was parked on an approval that your permission rules decided on their own (no card was ` +
|
|
756
774
|
`needed), so run ${outcome.taskId} should be resuming` +
|
|
@@ -838,8 +856,12 @@ function activeRunSelfHealBaseRow(outcome, signal, wayOut, following = false, ke
|
|
|
838
856
|
`cancel that run. That run may or may not have received your message — watch what it does next ` +
|
|
839
857
|
`before sending it again.`);
|
|
840
858
|
case 'running-cancelled':
|
|
841
|
-
return
|
|
842
|
-
`
|
|
859
|
+
return outcome.releaseConfirmedByEngine === true
|
|
860
|
+
? `You chose to cancel run ${outcome.taskId}. The engine confirmed it is no longer holding this session, ` +
|
|
861
|
+
`so sema is sending your message now.`
|
|
862
|
+
: `You chose to cancel run ${outcome.taskId}. The engine now reports that run as finished, so sema is ` +
|
|
863
|
+
`sending your message now; if that run has not fully let go of the session yet, you may have to send ` +
|
|
864
|
+
`it once more.`;
|
|
843
865
|
case 'running-cancel-timeout': {
|
|
844
866
|
const waited = `${String(Math.max(1, Math.round(outcome.waitedMs / 1000)))}s`;
|
|
845
867
|
if (outcome.aborted) {
|
|
@@ -872,6 +894,11 @@ function activeRunSelfHealBaseRow(outcome, signal, wayOut, following = false, ke
|
|
|
872
894
|
`not allowed to read. Either way sema has nothing it can act on here, so it did NOT cancel anything. ` +
|
|
873
895
|
`Your message was NOT sent; send it again (if the session really is free it will just run), or ${wayOut}.`);
|
|
874
896
|
case 'stale-park-cancelled':
|
|
897
|
+
if (outcome.releaseConfirmedByEngine === true) {
|
|
898
|
+
return (`Run ${outcome.taskId} was parked on an approval that no longer exists on the engine, so there was ` +
|
|
899
|
+
`nothing left for you to answer. You chose to cancel that run, and the engine confirmed it is no longer ` +
|
|
900
|
+
`holding this session, so sema is sending your message again now.`);
|
|
901
|
+
}
|
|
875
902
|
return (`Run ${outcome.taskId} was parked on an approval that no longer exists on the engine, so there was ` +
|
|
876
903
|
`nothing left for you to answer. You chose to cancel that run: the engine now reports it as finished, ` +
|
|
877
904
|
`so it will not resume — whatever that turn had left to do is not coming back. sema is sending your ` +
|
package/dist/compensations.js
CHANGED
|
@@ -30,7 +30,7 @@ export const MIGRATED_COMPENSATIONS = [
|
|
|
30
30
|
},
|
|
31
31
|
{
|
|
32
32
|
id: 'T36',
|
|
33
|
-
what: '
|
|
33
|
+
what: '子代终态 tick 缺席时(老服务端 / 丢帧 / 断流)四处防御 sweep 兜住面板行,不让它们永远转圈;终态 tick 在场时按它落终态',
|
|
34
34
|
disposition: 'in-library',
|
|
35
35
|
libraryHalf: 'adapt.ts settlePanelTasks 的四个调用点(tool_end 关卡 / result / turn 末 / abort)',
|
|
36
36
|
chromeArm: 'inline_task_stats',
|
|
@@ -6,6 +6,7 @@ export interface DisplayFace {
|
|
|
6
6
|
readonly unsafe: RegExp | null;
|
|
7
7
|
readonly fold: boolean;
|
|
8
8
|
readonly mark: DisplayMark;
|
|
9
|
+
readonly keepBlanks?: boolean;
|
|
9
10
|
}
|
|
10
11
|
export declare const LEGACY_ESCAPE_FACE: DisplayFace;
|
|
11
12
|
export declare const LEGACY_LABEL_FACE: DisplayFace;
|
|
@@ -20,5 +21,17 @@ export interface DisplayUntrustedOptions {
|
|
|
20
21
|
readonly keepLayout?: boolean;
|
|
21
22
|
readonly mark?: DisplayMark;
|
|
22
23
|
readonly max?: number;
|
|
24
|
+
readonly escapeBackslashes?: boolean;
|
|
25
|
+
readonly blanks?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export interface DisplayMarkSpan {
|
|
28
|
+
readonly start: number;
|
|
29
|
+
readonly end: number;
|
|
30
|
+
readonly codePoint: number;
|
|
31
|
+
}
|
|
32
|
+
export interface DisplayUntrustedMarked {
|
|
33
|
+
readonly text: string;
|
|
34
|
+
readonly marks: readonly DisplayMarkSpan[];
|
|
23
35
|
}
|
|
24
36
|
export declare function displayUntrusted(text: string, opts?: DisplayUntrustedOptions): string;
|
|
37
|
+
export declare function displayUntrustedMarks(text: string, opts?: DisplayUntrustedOptions): DisplayUntrustedMarked;
|