@vincemakes/kiso-core 0.1.0
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/LICENSE +21 -0
- package/README.md +9 -0
- package/dist/errors.d.ts +9 -0
- package/dist/errors.js +29 -0
- package/dist/governance/delivery.d.ts +35 -0
- package/dist/governance/delivery.js +47 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +13 -0
- package/dist/kernel/compaction.d.ts +60 -0
- package/dist/kernel/compaction.js +117 -0
- package/dist/kernel/event-log.d.ts +44 -0
- package/dist/kernel/event-log.js +51 -0
- package/dist/kernel/hooks.d.ts +52 -0
- package/dist/kernel/hooks.js +16 -0
- package/dist/kernel/ledger.d.ts +43 -0
- package/dist/kernel/ledger.js +88 -0
- package/dist/kernel/loop.d.ts +97 -0
- package/dist/kernel/loop.js +793 -0
- package/dist/kernel/mode.d.ts +26 -0
- package/dist/kernel/mode.js +21 -0
- package/dist/kernel/permission.d.ts +27 -0
- package/dist/kernel/permission.js +20 -0
- package/dist/kernel/project.d.ts +43 -0
- package/dist/kernel/project.js +287 -0
- package/dist/protocol/adapter.d.ts +77 -0
- package/dist/protocol/adapter.js +44 -0
- package/dist/protocol/events.d.ts +408 -0
- package/dist/protocol/events.js +230 -0
- package/dist/protocol/index.d.ts +3 -0
- package/dist/protocol/index.js +3 -0
- package/dist/protocol/messages.d.ts +113 -0
- package/dist/protocol/messages.js +17 -0
- package/dist/tools/registry.d.ts +28 -0
- package/dist/tools/registry.js +53 -0
- package/dist/tools/tool.d.ts +72 -0
- package/dist/tools/tool.js +21 -0
- package/dist/tools/validate.d.ts +11 -0
- package/dist/tools/validate.js +28 -0
- package/package.json +53 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* L2 — the ReAct loop. The kernel's only loop; everything else is harness.
|
|
3
|
+
*
|
|
4
|
+
* An async generator that yields every event as it happens (never buffers a
|
|
5
|
+
* turn into a list — the agno failure), and converges on exactly one
|
|
6
|
+
* `terminal` event per run (ADR-0004).
|
|
7
|
+
*
|
|
8
|
+
* SINGLE TRUTH (Phase B): the loop holds ONE EventLog. Messages are never
|
|
9
|
+
* stored alongside it — every adapter call derives them via
|
|
10
|
+
* `projectMessages(log.all)` (kernel/project.ts). A fresh log encodes the
|
|
11
|
+
* seed `messages` into events first, so even a one-shot call replays
|
|
12
|
+
* exactly. Compaction is recorded as a `compacted` event and re-applied by
|
|
13
|
+
* the projection, keeping the replay identical to the live run.
|
|
14
|
+
*
|
|
15
|
+
* Per iteration:
|
|
16
|
+
* assemble (onUserMessage / onPreLlm)
|
|
17
|
+
* → adapter.stream(): events yielded straight through, tool calls collected
|
|
18
|
+
* → execute: validation → permission (onPreTool) → handler → rewrite
|
|
19
|
+
* (onPostTool), concurrency-safe calls batched parallel, the rest serial
|
|
20
|
+
* → tool_result events appended
|
|
21
|
+
* no tool calls / maxTurns / abort / max_tokens → terminal event, return
|
|
22
|
+
*
|
|
23
|
+
* Retry lives HERE and only here (ADR-0005): a retryable StructuredError
|
|
24
|
+
* from the adapter is retried with backoff inside the generator frame — and
|
|
25
|
+
* ONLY before anything streamed (Phase B): once a text delta or tool call
|
|
26
|
+
* left the adapter, a failure is an `error` terminal, never a silent
|
|
27
|
+
* re-stream that duplicates output or tool calls.
|
|
28
|
+
*/
|
|
29
|
+
import { type Adapter, type AbortSignalLike } from "../protocol/adapter.js";
|
|
30
|
+
import type { Event, StructuredError } from "../protocol/events.js";
|
|
31
|
+
import { EventLog } from "./event-log.js";
|
|
32
|
+
import type { EventInput } from "./event-log.js";
|
|
33
|
+
import type { AssistantBlock, AssistantMessage, Message, ToolResultMessage } from "../protocol/messages.js";
|
|
34
|
+
import { ToolRegistry } from "../tools/registry.js";
|
|
35
|
+
import type { HookHost } from "./hooks.js";
|
|
36
|
+
import type { ModeProfile } from "./mode.js";
|
|
37
|
+
import { type PermissionDecision } from "./permission.js";
|
|
38
|
+
export interface LoopConfig {
|
|
39
|
+
readonly adapter: Adapter;
|
|
40
|
+
readonly model: string;
|
|
41
|
+
readonly systemPrompt?: string;
|
|
42
|
+
readonly registry: ToolRegistry;
|
|
43
|
+
readonly hooks?: HookHost;
|
|
44
|
+
readonly modes?: readonly ModeProfile[];
|
|
45
|
+
/** Active mode name; applies visibleToolNames structurally. */
|
|
46
|
+
readonly mode?: string;
|
|
47
|
+
readonly maxTurns?: number;
|
|
48
|
+
readonly maxRetries?: number;
|
|
49
|
+
/**
|
|
50
|
+
* Seed history. When a `log` is provided, the log IS the truth and this
|
|
51
|
+
* is only used if the log is empty. See ADR-0002 / kernel/project.ts.
|
|
52
|
+
*/
|
|
53
|
+
readonly messages?: readonly Message[];
|
|
54
|
+
/** The run's event log. Pass the session's log to make this run durable. */
|
|
55
|
+
readonly log?: EventLog;
|
|
56
|
+
/** Auto-compaction: when the estimated context exceeds the threshold,
|
|
57
|
+
* microcompact old tool results before the next model call. */
|
|
58
|
+
readonly compaction?: {
|
|
59
|
+
readonly thresholdTokens: number;
|
|
60
|
+
};
|
|
61
|
+
readonly signal?: AbortSignalLike;
|
|
62
|
+
readonly temperature?: number;
|
|
63
|
+
readonly maxTokens?: number;
|
|
64
|
+
/**
|
|
65
|
+
* Phase D: the channel that resolves a `defer` permission. When the
|
|
66
|
+
* onPreTool hook defers, the loop persists a `permission_requested`
|
|
67
|
+
* event, yields it, and AWAITS this promise — the same run resumes when
|
|
68
|
+
* a human decides. Absent, a defer degrades to an honest denial.
|
|
69
|
+
*/
|
|
70
|
+
readonly resolveApproval?: (decisionId: string) => Promise<PermissionDecision>;
|
|
71
|
+
/**
|
|
72
|
+
* 第四轮(对抗): a verdict the human ALREADY gave before an abort landed.
|
|
73
|
+
* The abort path consults this BEFORE yielding the aborted terminal: a
|
|
74
|
+
* consumed verdict must be recorded (exactly once), never lost — the
|
|
75
|
+
* human's decision outranks the abort.
|
|
76
|
+
*/
|
|
77
|
+
readonly approvalVerdict?: (decisionId: string) => boolean | undefined;
|
|
78
|
+
/**
|
|
79
|
+
* C 组: the channel that resolves a failed NON-idempotent execution.
|
|
80
|
+
* The loop persists `uncertain_pending`, yields it, and AWAITS the
|
|
81
|
+
* human verdict — no next model turn, no sibling tool, no auto-retry.
|
|
82
|
+
* Absent, the failure is recorded `abandoned` (never retried).
|
|
83
|
+
*/
|
|
84
|
+
readonly resolveUncertainty?: (executionId: string) => Promise<"rerun" | "abandoned">;
|
|
85
|
+
/** 第四轮(对抗): the uncertainty twin of `approvalVerdict`. */
|
|
86
|
+
readonly uncertaintyVerdict?: (executionId: string) => "rerun" | "abandoned" | undefined;
|
|
87
|
+
}
|
|
88
|
+
export declare const DEFAULT_MAX_TURNS = 10;
|
|
89
|
+
export declare const DEFAULT_MAX_RETRIES = 2;
|
|
90
|
+
export declare function loop(config: LoopConfig): AsyncGenerator<Event>;
|
|
91
|
+
/**
|
|
92
|
+
* Adapter exceptions → StructuredError. Anything already shaped like one
|
|
93
|
+
* passes through; everything else is `unknown` — never a regex over error
|
|
94
|
+
* text (ADR-0005).
|
|
95
|
+
*/
|
|
96
|
+
export declare function toStructuredError(err: unknown): StructuredError;
|
|
97
|
+
export type { EventInput, AssistantBlock, AssistantMessage, Message, ToolResultMessage };
|