@itookit/dsht 0.5.1 → 0.5.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/README.i18n.yaml +2 -2
- package/README.md +4 -2
- package/README.zh.md +6 -4
- package/dist/catalog/controller.d.ts +26 -6
- package/dist/catalog/controller.js +73 -45
- package/dist/catalog/index.d.ts +1 -0
- package/dist/cli/dsht.js +4 -1
- package/dist/cli/startup.js +30 -11
- package/dist/cli/verifier.d.ts +4 -0
- package/dist/cli/verifier.js +28 -5
- package/dist/contracts.d.ts +20 -5
- package/dist/controller/connection-streams.d.ts +22 -0
- package/dist/controller/connection-streams.js +105 -0
- package/dist/controller/connection.d.ts +14 -3
- package/dist/controller/connection.js +40 -69
- package/dist/controller/controller.d.ts +17 -233
- package/dist/controller/controller.js +108 -811
- package/dist/controller/foreground.d.ts +44 -0
- package/dist/controller/foreground.js +79 -0
- package/dist/controller/loop-coordinator.d.ts +48 -0
- package/dist/controller/loop-coordinator.js +647 -0
- package/dist/controller/verifier.d.ts +4 -0
- package/dist/cost/controller.d.ts +1 -1
- package/dist/cost/controller.js +12 -5
- package/dist/cost/scanner.js +1 -0
- package/dist/session/controller.d.ts +23 -35
- package/dist/session/controller.js +113 -363
- package/dist/session/history-reader.d.ts +32 -0
- package/dist/session/history-reader.js +170 -0
- package/dist/session/index.d.ts +1 -1
- package/dist/session/info.d.ts +3 -38
- package/dist/session/info.js +14 -1
- package/dist/session/interactions.d.ts +26 -0
- package/dist/session/interactions.js +75 -0
- package/dist/session/navigator.d.ts +47 -0
- package/dist/session/navigator.js +158 -0
- package/dist/session/prompt-backfill.d.ts +23 -0
- package/dist/session/prompt-backfill.js +88 -0
- package/dist/session/state.d.ts +20 -0
- package/dist/session/state.js +1 -0
- package/dist/session/telemetry.d.ts +15 -6
- package/dist/session/telemetry.js +44 -7
- package/dist/session/transcript.d.ts +5 -1
- package/dist/slash/index.d.ts +1 -1
- package/dist/slash/parse.d.ts +2 -126
- package/dist/slash/registry.d.ts +1 -1
- package/dist/slash/types.d.ts +126 -0
- package/dist/slash/types.js +1 -0
- package/dist/state.d.ts +5 -17
- package/dist/state.js +1 -1
- package/dist/transport/client.d.ts +4 -3
- package/dist/transport/client.js +71 -25
- package/dist/ui/app.js +86 -301
- package/dist/ui/chat/shell-view.d.ts +2 -0
- package/dist/ui/chat/shell-view.js +8 -0
- package/dist/ui/chat/use-history-view.d.ts +69 -0
- package/dist/ui/chat/use-history-view.js +123 -0
- package/dist/ui/dialogs/use-panels.d.ts +53 -0
- package/dist/ui/dialogs/use-panels.js +51 -0
- package/dist/ui/input/use-composer.d.ts +35 -0
- package/dist/ui/input/use-composer.js +109 -0
- package/dist/ui/input/use-deferred-lines.d.ts +16 -0
- package/dist/ui/input/use-deferred-lines.js +54 -0
- package/dist/ui/input/use-history-recall.d.ts +20 -0
- package/dist/ui/input/use-history-recall.js +47 -0
- package/package.json +1 -1
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { ForegroundKind, ForegroundSnapshot } from '../contracts.ts';
|
|
2
|
+
type ForegroundEvent = {
|
|
3
|
+
phase: 'queued';
|
|
4
|
+
kind: ForegroundKind;
|
|
5
|
+
label: string;
|
|
6
|
+
} | {
|
|
7
|
+
phase: 'begin';
|
|
8
|
+
id: number;
|
|
9
|
+
kind: ForegroundKind;
|
|
10
|
+
label: string;
|
|
11
|
+
} | {
|
|
12
|
+
phase: 'end';
|
|
13
|
+
id: number;
|
|
14
|
+
kind: ForegroundKind;
|
|
15
|
+
cancelled: boolean;
|
|
16
|
+
};
|
|
17
|
+
/** Owns scheduling only; the application publishes state and reports action failures. */
|
|
18
|
+
export declare class ForegroundSlot {
|
|
19
|
+
private readonly listener;
|
|
20
|
+
private current?;
|
|
21
|
+
private readonly owner;
|
|
22
|
+
private readonly waiters;
|
|
23
|
+
private granted;
|
|
24
|
+
private closed;
|
|
25
|
+
private sequence;
|
|
26
|
+
constructor(listener: {
|
|
27
|
+
changed(started: boolean): void;
|
|
28
|
+
trace(event: ForegroundEvent): void;
|
|
29
|
+
});
|
|
30
|
+
/** Only display data crosses the UI boundary; the abort controller stays private. */
|
|
31
|
+
get snapshot(): ForegroundSnapshot | undefined;
|
|
32
|
+
/** An inherited async context is an owner only while that exact operation is active. */
|
|
33
|
+
private ownsCurrent;
|
|
34
|
+
/** Nested work shares its owner's signal. Other callers are refused or wait in arrival order.
|
|
35
|
+
* Cancellation is cooperative: admitted work keeps its result/error, and no new nested work starts
|
|
36
|
+
* after cancellation. The slot stays occupied until the admitted work settles.
|
|
37
|
+
*/
|
|
38
|
+
run<T>(kind: ForegroundKind, label: string, work: (signal: AbortSignal) => Promise<T>, wait?: boolean): Promise<T | undefined>;
|
|
39
|
+
/** Abort cooperatively, keeping the slot until work has settled. */
|
|
40
|
+
cancel(): boolean;
|
|
41
|
+
/** Permanently refuse new claims, abort the occupant and release all waiting callers. */
|
|
42
|
+
close(): void;
|
|
43
|
+
}
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/** Admission and cancellation for the application's single foreground operation. */
|
|
2
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
3
|
+
/** Owns scheduling only; the application publishes state and reports action failures. */
|
|
4
|
+
export class ForegroundSlot {
|
|
5
|
+
listener;
|
|
6
|
+
current;
|
|
7
|
+
owner = new AsyncLocalStorage();
|
|
8
|
+
waiters = [];
|
|
9
|
+
granted = false;
|
|
10
|
+
closed = false;
|
|
11
|
+
sequence = 0;
|
|
12
|
+
constructor(listener) {
|
|
13
|
+
this.listener = listener;
|
|
14
|
+
}
|
|
15
|
+
/** Only display data crosses the UI boundary; the abort controller stays private. */
|
|
16
|
+
get snapshot() { return this.current?.snapshot; }
|
|
17
|
+
/** An inherited async context is an owner only while that exact operation is active. */
|
|
18
|
+
ownsCurrent() {
|
|
19
|
+
return this.current !== undefined && this.owner.getStore() === this.current.snapshot.id;
|
|
20
|
+
}
|
|
21
|
+
/** Nested work shares its owner's signal. Other callers are refused or wait in arrival order.
|
|
22
|
+
* Cancellation is cooperative: admitted work keeps its result/error, and no new nested work starts
|
|
23
|
+
* after cancellation. The slot stays occupied until the admitted work settles.
|
|
24
|
+
*/
|
|
25
|
+
async run(kind, label, work, wait = false) {
|
|
26
|
+
if (this.closed)
|
|
27
|
+
return undefined;
|
|
28
|
+
if (this.ownsCurrent()) {
|
|
29
|
+
const signal = this.current.abort.signal;
|
|
30
|
+
return signal.aborted ? undefined : await work(signal);
|
|
31
|
+
}
|
|
32
|
+
if (this.current !== undefined || this.granted) {
|
|
33
|
+
if (!wait)
|
|
34
|
+
return undefined;
|
|
35
|
+
this.listener.trace({ phase: 'queued', kind, label });
|
|
36
|
+
await new Promise(resolve => this.waiters.push(resolve));
|
|
37
|
+
this.granted = false;
|
|
38
|
+
if (this.closed)
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
const snapshot = Object.freeze({ id: ++this.sequence, kind, label, startedAt: Date.now() });
|
|
42
|
+
const operation = { snapshot, abort: new AbortController() };
|
|
43
|
+
this.current = operation;
|
|
44
|
+
try {
|
|
45
|
+
this.listener.trace({ phase: 'begin', id: snapshot.id, kind, label });
|
|
46
|
+
this.listener.changed(true);
|
|
47
|
+
if (operation.abort.signal.aborted)
|
|
48
|
+
return undefined;
|
|
49
|
+
return await this.owner.run(snapshot.id, () => work(operation.abort.signal));
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
this.current = undefined;
|
|
53
|
+
// Reserve before publishing: an observer may synchronously try to claim the empty slot.
|
|
54
|
+
const next = this.waiters.shift();
|
|
55
|
+
this.granted = next !== undefined;
|
|
56
|
+
try {
|
|
57
|
+
this.listener.trace({ phase: 'end', id: snapshot.id, kind, cancelled: operation.abort.signal.aborted });
|
|
58
|
+
this.listener.changed(false);
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
next?.();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/** Abort cooperatively, keeping the slot until work has settled. */
|
|
66
|
+
cancel() {
|
|
67
|
+
if (this.current === undefined)
|
|
68
|
+
return false;
|
|
69
|
+
this.current.abort.abort();
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
/** Permanently refuse new claims, abort the occupant and release all waiting callers. */
|
|
73
|
+
close() {
|
|
74
|
+
this.closed = true;
|
|
75
|
+
this.cancel();
|
|
76
|
+
for (const wake of this.waiters.splice(0))
|
|
77
|
+
wake();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { ObjectValue } from '../json.ts';
|
|
2
|
+
import type { LoopProgress, LoopTerminalReason } from '../contracts.ts';
|
|
3
|
+
import { type LoopLimits, type LoopProtocol } from './loop.ts';
|
|
4
|
+
import { type VerifierPort } from './verifier.ts';
|
|
5
|
+
/** Application facts and effects a loop needs; no Controller, State or Transcript crosses here. */
|
|
6
|
+
export interface LoopHost {
|
|
7
|
+
facts(): {
|
|
8
|
+
sessionId?: string;
|
|
9
|
+
online: boolean;
|
|
10
|
+
busy: boolean;
|
|
11
|
+
pending: boolean;
|
|
12
|
+
ready: boolean;
|
|
13
|
+
};
|
|
14
|
+
reply(): string;
|
|
15
|
+
send(prompt: string): Promise<void>;
|
|
16
|
+
publish(failure?: string): void;
|
|
17
|
+
trace(event: string, detail: ObjectValue): void;
|
|
18
|
+
}
|
|
19
|
+
export interface LoopCoordinatorOptions {
|
|
20
|
+
directory: string;
|
|
21
|
+
verifier?: VerifierPort;
|
|
22
|
+
verdictRoot?: string;
|
|
23
|
+
deadlineMs?: number;
|
|
24
|
+
allowSelfFallback?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/** Owns the selected run and its lifetime, while ScoredLoop owns the pure scoring rules. */
|
|
27
|
+
export declare class LoopCoordinator {
|
|
28
|
+
private readonly host;
|
|
29
|
+
private readonly options;
|
|
30
|
+
private current?;
|
|
31
|
+
private closed;
|
|
32
|
+
constructor(host: LoopHost, options: LoopCoordinatorOptions);
|
|
33
|
+
get progress(): LoopProgress | undefined;
|
|
34
|
+
get sessionId(): string | undefined;
|
|
35
|
+
get verifierName(): string | undefined;
|
|
36
|
+
get forkedVerification(): boolean;
|
|
37
|
+
get selfScoring(): boolean;
|
|
38
|
+
start(protocol: LoopProtocol, limits: LoopLimits): Promise<void>;
|
|
39
|
+
stop(reason?: LoopTerminalReason): void;
|
|
40
|
+
answer(text: string): Promise<void>;
|
|
41
|
+
clearResult(): void;
|
|
42
|
+
forget(): void;
|
|
43
|
+
/** Called after application facts or transcript content change. */
|
|
44
|
+
changed(): void;
|
|
45
|
+
idle(sessionId: string): void;
|
|
46
|
+
/** Stop timers and verifier work before the application tears down the connection. */
|
|
47
|
+
close(): Promise<void>;
|
|
48
|
+
}
|