@4fu/arbor-interfaces 0.0.0-stage → 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 +187 -2
- package/agent.d.ts +202 -0
- package/agent.js +11 -0
- package/blocks.d.ts +56 -0
- package/blocks.js +11 -0
- package/channel.d.ts +61 -0
- package/channel.js +11 -0
- package/effects.d.ts +42 -0
- package/effects.js +11 -0
- package/environment.d.ts +109 -0
- package/environment.js +16 -0
- package/events.d.ts +162 -0
- package/events.js +4 -0
- package/hooks.d.ts +141 -0
- package/hooks.js +10 -0
- package/index.d.ts +29 -0
- package/index.js +10 -0
- package/journal.d.ts +87 -0
- package/journal.js +16 -0
- package/judge.d.ts +206 -0
- package/judge.js +13 -0
- package/notes.d.ts +215 -0
- package/notes.js +5 -0
- package/package.json +69 -4
- package/plugin.d.ts +52 -0
- package/plugin.js +13 -0
- package/refs.d.ts +49 -0
- package/refs.js +9 -0
- package/scheduler.d.ts +132 -0
- package/scheduler.js +21 -0
- package/settings.d.ts +64 -0
- package/settings.js +9 -0
- package/supervisor.d.ts +84 -0
- package/supervisor.js +11 -0
- package/task.d.ts +46 -0
- package/task.js +10 -0
- package/tools.d.ts +33 -0
- package/tools.js +10 -0
- package/windows.d.ts +81 -0
- package/windows.js +8 -0
- package/workspace.d.ts +113 -0
- package/workspace.js +9 -0
package/environment.d.ts
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `Environment` interface: skills, MCP servers and services - revisions,
|
|
3
|
+
* validation, the shared `/env` mount, deltas (docs/architecture.md#interfaces,
|
|
4
|
+
* docs/environment.md).
|
|
5
|
+
*
|
|
6
|
+
* The model changes the environment itself, with `reload`: copy, edit,
|
|
7
|
+
* validate, replace as a whole, record an environment revision, broadcast the
|
|
8
|
+
* delta. Each item has its own revision, so changes to different items never
|
|
9
|
+
* conflict. Two things are outside the model's reach: the value of a secret,
|
|
10
|
+
* and the built-in skills.
|
|
11
|
+
*
|
|
12
|
+
* The settings are an item like any other, at `/env/settings.json`, so the
|
|
13
|
+
* model changes its own identity, general rules, judge and model tiers the same
|
|
14
|
+
* way it changes a skill.
|
|
15
|
+
*/
|
|
16
|
+
import type { FunctionSpec } from "./agent.ts";
|
|
17
|
+
import type { EnvItemName, EnvItemRef, EnvRef } from "./refs.ts";
|
|
18
|
+
import type { Settings } from "./settings.ts";
|
|
19
|
+
import type { ArborErrorInfo } from "@4fu/arbor-errors";
|
|
20
|
+
export type EnvItemKind = "skill" | "mcp" | "service" | "settings";
|
|
21
|
+
/** One installed item. */
|
|
22
|
+
export interface EnvItem {
|
|
23
|
+
ref: EnvItemRef;
|
|
24
|
+
kind: EnvItemKind;
|
|
25
|
+
name: string;
|
|
26
|
+
/** One line: a name, a description and, for a skill, its path. */
|
|
27
|
+
description: string;
|
|
28
|
+
/** A skill's path under `/env`. */
|
|
29
|
+
path?: string;
|
|
30
|
+
revision: number;
|
|
31
|
+
time: number;
|
|
32
|
+
/** True for the built-in skills, which are read-only. */
|
|
33
|
+
builtin?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* An MCP server's functions, listed when the server was last validated. A
|
|
36
|
+
* server is a module of its own in code mode, so this is what the catalog
|
|
37
|
+
* declares and what `tool_search` answers (docs/tools.md#modules).
|
|
38
|
+
*/
|
|
39
|
+
functions?: readonly FunctionSpec[];
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* One draft of an environment item, waiting for `reload`. A window's draft
|
|
43
|
+
* names a path inside that window's workspace; a plugin's draft names a path on
|
|
44
|
+
* the host, beside the plugin's own files.
|
|
45
|
+
*/
|
|
46
|
+
export interface EnvDraft {
|
|
47
|
+
kind: EnvItemKind;
|
|
48
|
+
name: string;
|
|
49
|
+
/** Where the draft is: in the window's workspace, or a host path for a plugin. */
|
|
50
|
+
path: string;
|
|
51
|
+
/** The revision the draft was copied from; a newer one refuses the install. */
|
|
52
|
+
copiedFrom?: number;
|
|
53
|
+
}
|
|
54
|
+
export interface EnvValidation {
|
|
55
|
+
ok: boolean;
|
|
56
|
+
/** One entry per draft, so a retry acts only on what did not pass. */
|
|
57
|
+
items: ReadonlyArray<{
|
|
58
|
+
name: string;
|
|
59
|
+
ok: boolean;
|
|
60
|
+
error?: ArborErrorInfo;
|
|
61
|
+
}>;
|
|
62
|
+
}
|
|
63
|
+
export interface EnvRevision {
|
|
64
|
+
ref: EnvRef;
|
|
65
|
+
previous: EnvRef | null;
|
|
66
|
+
time: number;
|
|
67
|
+
window: string | null;
|
|
68
|
+
changes: ReadonlyArray<{
|
|
69
|
+
change: "added" | "changed" | "removed";
|
|
70
|
+
item: EnvItem;
|
|
71
|
+
}>;
|
|
72
|
+
}
|
|
73
|
+
/** What a live window is told changed since it opened. */
|
|
74
|
+
export interface EnvDelta {
|
|
75
|
+
revision: EnvRef;
|
|
76
|
+
previous: EnvRef;
|
|
77
|
+
items: ReadonlyArray<{
|
|
78
|
+
change: "added" | "changed" | "removed";
|
|
79
|
+
item: EnvItem;
|
|
80
|
+
}>;
|
|
81
|
+
}
|
|
82
|
+
export interface Environment {
|
|
83
|
+
/** The shared mount every window reads `/env` through. */
|
|
84
|
+
readonly mount: string;
|
|
85
|
+
/** The directory the mount is, on the host, which the file tools read. */
|
|
86
|
+
readonly directory: string;
|
|
87
|
+
revision(): Promise<EnvRef>;
|
|
88
|
+
list(): Promise<readonly EnvItem[]>;
|
|
89
|
+
/** An item's revisions, or the environment's when `item` is omitted. */
|
|
90
|
+
history(item?: EnvItemRef | EnvItemName): Promise<readonly EnvRevision[]>;
|
|
91
|
+
/** The settings, from `/env/settings.json`. Undefined until one is installed. */
|
|
92
|
+
settings(): Promise<Settings | undefined>;
|
|
93
|
+
/** Validate drafts: a skill parses, an MCP server starts and lists its functions. */
|
|
94
|
+
validate(drafts: readonly EnvDraft[]): Promise<EnvValidation>;
|
|
95
|
+
/**
|
|
96
|
+
* `reload({ install, remove })`. Replaces each item as a whole, or refuses
|
|
97
|
+
* and changes nothing. One call is one environment revision, so a call that
|
|
98
|
+
* both installs and removes lands as a single delta.
|
|
99
|
+
*/
|
|
100
|
+
install(drafts: readonly EnvDraft[], remove?: readonly (EnvItemRef | EnvItemName)[]): Promise<EnvRevision>;
|
|
101
|
+
/** `reload({ remove })`. */
|
|
102
|
+
remove(items: readonly (EnvItemRef | EnvItemName)[]): Promise<EnvRevision>;
|
|
103
|
+
/** What changed since a revision, for a live window's delta. */
|
|
104
|
+
delta(since: EnvRef): Promise<EnvDelta>;
|
|
105
|
+
/** Start every installed service again, after a host restart. */
|
|
106
|
+
resume(): Promise<void>;
|
|
107
|
+
/** Call one function of an installed MCP server, from a script in `code_exec`. */
|
|
108
|
+
call(server: string, fn: string, args: Record<string, unknown>): Promise<string>;
|
|
109
|
+
}
|
package/environment.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `Environment` interface: skills, MCP servers and services - revisions,
|
|
3
|
+
* validation, the shared `/env` mount, deltas (docs/architecture.md#interfaces,
|
|
4
|
+
* docs/environment.md).
|
|
5
|
+
*
|
|
6
|
+
* The model changes the environment itself, with `reload`: copy, edit,
|
|
7
|
+
* validate, replace as a whole, record an environment revision, broadcast the
|
|
8
|
+
* delta. Each item has its own revision, so changes to different items never
|
|
9
|
+
* conflict. Two things are outside the model's reach: the value of a secret,
|
|
10
|
+
* and the built-in skills.
|
|
11
|
+
*
|
|
12
|
+
* The settings are an item like any other, at `/env/settings.json`, so the
|
|
13
|
+
* model changes its own identity, general rules, judge and model tiers the same
|
|
14
|
+
* way it changes a skill.
|
|
15
|
+
*/
|
|
16
|
+
export {};
|
package/events.d.ts
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Events and the shapes a `Journal` read returns (docs/journal.md).
|
|
3
|
+
*/
|
|
4
|
+
import type { BlobRef, EventKind, EventRef, ExternalRef, LinkKind, MatchKind, Ref, Target, WindowRef } from "./refs.ts";
|
|
5
|
+
import type { ArborErrorInfo } from "@4fu/arbor-errors";
|
|
6
|
+
/** What an append carries. The journal assigns `ref`, `seq` and, when omitted, `time`. */
|
|
7
|
+
export interface EventInput {
|
|
8
|
+
kind: EventKind;
|
|
9
|
+
/** The window that wrote it; empty for an outside event not yet dispatched. */
|
|
10
|
+
window?: WindowRef | null;
|
|
11
|
+
body?: string | null;
|
|
12
|
+
targets?: readonly Target[];
|
|
13
|
+
refs?: readonly Ref[];
|
|
14
|
+
/** Links the host recorded. The new event is the `from` side of each. */
|
|
15
|
+
links?: readonly LinkInput[];
|
|
16
|
+
/** Native id of an outside message, with a short channel prefix: `qq:12345`. */
|
|
17
|
+
external?: ExternalRef | null;
|
|
18
|
+
blobs?: readonly BlobRef[];
|
|
19
|
+
/** Assigned by the journal when omitted; the journal's clock is the only writer. */
|
|
20
|
+
time?: number;
|
|
21
|
+
}
|
|
22
|
+
/** One link between refs. */
|
|
23
|
+
export interface Link {
|
|
24
|
+
kind: LinkKind;
|
|
25
|
+
from: Ref;
|
|
26
|
+
to: Ref;
|
|
27
|
+
/** Relative strength; a bare cite is weaker than a declared link. */
|
|
28
|
+
weight: number;
|
|
29
|
+
time: number;
|
|
30
|
+
}
|
|
31
|
+
/** A link an append declares. `from` is the event being appended. */
|
|
32
|
+
export interface LinkInput {
|
|
33
|
+
kind: LinkKind;
|
|
34
|
+
/**
|
|
35
|
+
* The ref it names. A link goes from what names it to what it names, so a
|
|
36
|
+
* trace walks `from` to `to` back to where something came from.
|
|
37
|
+
*/
|
|
38
|
+
to: Ref;
|
|
39
|
+
weight?: number;
|
|
40
|
+
}
|
|
41
|
+
/** A redaction, shown in place of the erased content. */
|
|
42
|
+
export interface Redaction {
|
|
43
|
+
/** The event that redacted this one. */
|
|
44
|
+
by: EventRef;
|
|
45
|
+
reason: string;
|
|
46
|
+
time: number;
|
|
47
|
+
}
|
|
48
|
+
/** One immutable record. */
|
|
49
|
+
export interface Event {
|
|
50
|
+
ref: EventRef;
|
|
51
|
+
/** The event's place in the one global order. Only grows. */
|
|
52
|
+
seq: number;
|
|
53
|
+
window: WindowRef | null;
|
|
54
|
+
time: number;
|
|
55
|
+
kind: EventKind;
|
|
56
|
+
targets: Target[];
|
|
57
|
+
refs: Ref[];
|
|
58
|
+
links: Link[];
|
|
59
|
+
external: ExternalRef | null;
|
|
60
|
+
blobs: BlobRef[];
|
|
61
|
+
body: string | null;
|
|
62
|
+
redacted: Redaction | null;
|
|
63
|
+
}
|
|
64
|
+
/** Options for a chronological listing. */
|
|
65
|
+
export interface ListOptions {
|
|
66
|
+
window?: WindowRef;
|
|
67
|
+
kinds?: readonly EventKind[];
|
|
68
|
+
targets?: readonly Target[];
|
|
69
|
+
external?: string;
|
|
70
|
+
/** Only events after this sequence number. */
|
|
71
|
+
afterSeq?: number;
|
|
72
|
+
beforeSeq?: number;
|
|
73
|
+
limit?: number;
|
|
74
|
+
offset?: number;
|
|
75
|
+
}
|
|
76
|
+
/** One page of a read. The bound is reported every time (docs/prompting.md). */
|
|
77
|
+
export interface Page<T> {
|
|
78
|
+
items: T[];
|
|
79
|
+
/** How many items match in total, before the page cut. */
|
|
80
|
+
total: number;
|
|
81
|
+
limit: number;
|
|
82
|
+
/** The exact call that pages the rest. */
|
|
83
|
+
nextCall: string;
|
|
84
|
+
}
|
|
85
|
+
export type EventPage = Page<Event>;
|
|
86
|
+
/** Options for `around`. */
|
|
87
|
+
export interface AroundOptions {
|
|
88
|
+
before?: number;
|
|
89
|
+
after?: number;
|
|
90
|
+
}
|
|
91
|
+
/** Options for `search`. */
|
|
92
|
+
export interface SearchOptions {
|
|
93
|
+
kinds?: readonly EventKind[];
|
|
94
|
+
targets?: readonly Target[];
|
|
95
|
+
window?: WindowRef;
|
|
96
|
+
/** Find the stored copy of an outside message by its native id. */
|
|
97
|
+
external?: string;
|
|
98
|
+
afterSeq?: number;
|
|
99
|
+
beforeSeq?: number;
|
|
100
|
+
limit?: number;
|
|
101
|
+
offset?: number;
|
|
102
|
+
}
|
|
103
|
+
/** One search hit: its ref and window, plus what matched. */
|
|
104
|
+
export interface SearchHit {
|
|
105
|
+
ref: EventRef;
|
|
106
|
+
seq: number;
|
|
107
|
+
window: WindowRef | null;
|
|
108
|
+
kind: EventKind;
|
|
109
|
+
time: number;
|
|
110
|
+
match: MatchKind;
|
|
111
|
+
/** Relevance in 0..1 within its index; higher is better. */
|
|
112
|
+
score: number;
|
|
113
|
+
/** The event's opening words, for a one-line result. */
|
|
114
|
+
summary: string;
|
|
115
|
+
}
|
|
116
|
+
export type SearchPage = Page<SearchHit>;
|
|
117
|
+
/** Options for `links`. */
|
|
118
|
+
export interface LinksOptions {
|
|
119
|
+
offset?: number;
|
|
120
|
+
limit?: number;
|
|
121
|
+
}
|
|
122
|
+
/** One related item, by weight. */
|
|
123
|
+
export interface RelatedItem {
|
|
124
|
+
ref: Ref;
|
|
125
|
+
kind: LinkKind;
|
|
126
|
+
weight: number;
|
|
127
|
+
direction: "out" | "in";
|
|
128
|
+
window: WindowRef | null;
|
|
129
|
+
time: number;
|
|
130
|
+
summary: string;
|
|
131
|
+
}
|
|
132
|
+
export type LinkPage = Page<RelatedItem>;
|
|
133
|
+
/** Options for `trace`. */
|
|
134
|
+
export interface TraceOptions {
|
|
135
|
+
/** How many steps back from the traced ref. */
|
|
136
|
+
maxHops?: number;
|
|
137
|
+
/** How many nodes the walk may visit. */
|
|
138
|
+
maxNodes?: number;
|
|
139
|
+
}
|
|
140
|
+
/** One node of a trace: where a ref came from, back to the original input. */
|
|
141
|
+
export interface TraceNode {
|
|
142
|
+
ref: Ref;
|
|
143
|
+
kind?: EventKind;
|
|
144
|
+
window: WindowRef | null;
|
|
145
|
+
time: number;
|
|
146
|
+
summary: string;
|
|
147
|
+
/** True at an outside message, or at a ref the walk stopped on. */
|
|
148
|
+
origin: boolean;
|
|
149
|
+
from: TraceNode[];
|
|
150
|
+
}
|
|
151
|
+
/** A target a window is behind on. */
|
|
152
|
+
export interface TargetGap {
|
|
153
|
+
target: Target;
|
|
154
|
+
/** The newest event on the target. */
|
|
155
|
+
latest: number;
|
|
156
|
+
/** The newest event on the target the window has seen. */
|
|
157
|
+
watermark: number;
|
|
158
|
+
/** How many events the window has not seen. */
|
|
159
|
+
count: number;
|
|
160
|
+
}
|
|
161
|
+
/** One refusal a `Journal` returns, in the core's error shape. */
|
|
162
|
+
export type JournalError = ArborErrorInfo;
|
package/events.js
ADDED
package/hooks.d.ts
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hooks: how a deployment or a plugin adds policy without replacing a module
|
|
3
|
+
* (docs/architecture.md#hooks).
|
|
4
|
+
*
|
|
5
|
+
* The framework sets no policy of its own. Each hook can observe, change or
|
|
6
|
+
* refuse, and refuses in the core's error shape, so the model always reads the
|
|
7
|
+
* same kind of refusal. Permissions, privacy review, budgets and approvals are
|
|
8
|
+
* built from these.
|
|
9
|
+
*/
|
|
10
|
+
import type { ArborErrorInfo } from "@4fu/arbor-errors";
|
|
11
|
+
import type { Delivery, RenderedPrompt, ToolCall, ToolResult } from "./agent.ts";
|
|
12
|
+
import type { Block } from "./blocks.ts";
|
|
13
|
+
import type { Event, EventInput } from "./events.ts";
|
|
14
|
+
import type { Effect } from "./effects.ts";
|
|
15
|
+
import type { EnvDraft, EnvRevision } from "./environment.ts";
|
|
16
|
+
import type { JudgeAnswer, JudgeRequest } from "./judge.ts";
|
|
17
|
+
import type { NoteWriteInput } from "./notes.ts";
|
|
18
|
+
import type { TaskInput } from "./task.ts";
|
|
19
|
+
import type { ServiceStatus } from "./supervisor.ts";
|
|
20
|
+
import type { WindowRef } from "./refs.ts";
|
|
21
|
+
import type { Handoff } from "./windows.ts";
|
|
22
|
+
/** What a hook answers. `context` carries what it changed. */
|
|
23
|
+
export type HookOutcome<T> = {
|
|
24
|
+
allow: true;
|
|
25
|
+
context?: T;
|
|
26
|
+
} | {
|
|
27
|
+
allow: false;
|
|
28
|
+
error: ArborErrorInfo;
|
|
29
|
+
};
|
|
30
|
+
export interface AppendContext {
|
|
31
|
+
input: EventInput;
|
|
32
|
+
event?: Event;
|
|
33
|
+
}
|
|
34
|
+
export interface DispatchContext {
|
|
35
|
+
task: TaskInput;
|
|
36
|
+
/** The judge's answer, when the judge decided. */
|
|
37
|
+
answer?: JudgeAnswer;
|
|
38
|
+
/** The window the task went to, or `null` when a new window opens. */
|
|
39
|
+
window?: WindowRef | null;
|
|
40
|
+
}
|
|
41
|
+
export interface JudgeContext {
|
|
42
|
+
request: JudgeRequest;
|
|
43
|
+
answer?: JudgeAnswer;
|
|
44
|
+
/** The state the judge saw, after scrubbing. */
|
|
45
|
+
scrubbed?: boolean;
|
|
46
|
+
}
|
|
47
|
+
export interface WindowStartContext {
|
|
48
|
+
window: WindowRef;
|
|
49
|
+
task: TaskInput;
|
|
50
|
+
continuation?: {
|
|
51
|
+
previous: WindowRef;
|
|
52
|
+
handoff?: Handoff;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export interface WindowEndContext {
|
|
56
|
+
window: WindowRef;
|
|
57
|
+
handoff?: Handoff;
|
|
58
|
+
reason: string;
|
|
59
|
+
}
|
|
60
|
+
export interface WindowContinueContext {
|
|
61
|
+
window: WindowRef;
|
|
62
|
+
previous: WindowRef;
|
|
63
|
+
handoff?: Handoff;
|
|
64
|
+
/** Set after the hard limit: the window was reset mid-task. */
|
|
65
|
+
midTaskReset?: boolean;
|
|
66
|
+
}
|
|
67
|
+
export interface ModelRequestContext {
|
|
68
|
+
window: WindowRef;
|
|
69
|
+
prompt: RenderedPrompt;
|
|
70
|
+
inputs: readonly Block[];
|
|
71
|
+
}
|
|
72
|
+
export interface DeliveryContext {
|
|
73
|
+
window: WindowRef;
|
|
74
|
+
delivery: Delivery;
|
|
75
|
+
}
|
|
76
|
+
export interface ToolCallContext {
|
|
77
|
+
window: WindowRef;
|
|
78
|
+
call: ToolCall;
|
|
79
|
+
result?: ToolResult;
|
|
80
|
+
}
|
|
81
|
+
/** What `beforeEffect` answers: release, hold for approval, or drop. */
|
|
82
|
+
export type EffectOutcome = {
|
|
83
|
+
action: "release";
|
|
84
|
+
} | {
|
|
85
|
+
action: "hold";
|
|
86
|
+
approval?: string;
|
|
87
|
+
} | {
|
|
88
|
+
action: "drop";
|
|
89
|
+
error: ArborErrorInfo;
|
|
90
|
+
};
|
|
91
|
+
/** An effect the host holds until an approval releases or drops it. */
|
|
92
|
+
export interface EffectHold {
|
|
93
|
+
effect: Effect;
|
|
94
|
+
release(): Promise<void>;
|
|
95
|
+
drop(reason: string): Promise<void>;
|
|
96
|
+
}
|
|
97
|
+
export interface EffectContext {
|
|
98
|
+
effect: Effect;
|
|
99
|
+
/** The executor that owns it. */
|
|
100
|
+
executor?: string;
|
|
101
|
+
}
|
|
102
|
+
export interface NoteWriteContext {
|
|
103
|
+
window: WindowRef;
|
|
104
|
+
input: NoteWriteInput;
|
|
105
|
+
/** The revision that was written, for `afterNoteWrite`. */
|
|
106
|
+
revision?: number;
|
|
107
|
+
}
|
|
108
|
+
export interface ReloadContext {
|
|
109
|
+
window: WindowRef;
|
|
110
|
+
drafts: readonly EnvDraft[];
|
|
111
|
+
remove?: readonly string[];
|
|
112
|
+
revision?: EnvRevision;
|
|
113
|
+
}
|
|
114
|
+
export interface ServiceStateContext {
|
|
115
|
+
service: string;
|
|
116
|
+
status: ServiceStatus;
|
|
117
|
+
}
|
|
118
|
+
export interface Hooks {
|
|
119
|
+
beforeAppend?(context: AppendContext): Promise<HookOutcome<AppendContext>> | HookOutcome<AppendContext>;
|
|
120
|
+
afterAppend?(context: AppendContext): Promise<void> | void;
|
|
121
|
+
beforeDispatch?(context: DispatchContext): Promise<HookOutcome<DispatchContext>> | HookOutcome<DispatchContext>;
|
|
122
|
+
afterDispatch?(context: DispatchContext): Promise<void> | void;
|
|
123
|
+
beforeJudge?(context: JudgeContext): Promise<HookOutcome<JudgeContext>> | HookOutcome<JudgeContext>;
|
|
124
|
+
afterJudge?(context: JudgeContext): Promise<void> | void;
|
|
125
|
+
windowStart?(context: WindowStartContext): Promise<HookOutcome<WindowStartContext>> | HookOutcome<WindowStartContext>;
|
|
126
|
+
windowEnd?(context: WindowEndContext): Promise<HookOutcome<WindowEndContext>> | HookOutcome<WindowEndContext>;
|
|
127
|
+
windowContinue?(context: WindowContinueContext): Promise<HookOutcome<WindowContinueContext>> | HookOutcome<WindowContinueContext>;
|
|
128
|
+
beforeModelRequest?(context: ModelRequestContext): Promise<HookOutcome<ModelRequestContext>> | HookOutcome<ModelRequestContext>;
|
|
129
|
+
beforeDelivery?(context: DeliveryContext): Promise<HookOutcome<DeliveryContext>> | HookOutcome<DeliveryContext>;
|
|
130
|
+
beforeToolCall?(context: ToolCallContext): Promise<HookOutcome<ToolCallContext>> | HookOutcome<ToolCallContext>;
|
|
131
|
+
afterToolCall?(context: ToolCallContext): Promise<void> | void;
|
|
132
|
+
beforeEffect?(context: EffectContext): Promise<EffectOutcome> | EffectOutcome;
|
|
133
|
+
beforeNoteWrite?(context: NoteWriteContext): Promise<HookOutcome<NoteWriteContext>> | HookOutcome<NoteWriteContext>;
|
|
134
|
+
afterNoteWrite?(context: NoteWriteContext): Promise<void> | void;
|
|
135
|
+
beforeReload?(context: ReloadContext): Promise<HookOutcome<ReloadContext>> | HookOutcome<ReloadContext>;
|
|
136
|
+
afterReload?(context: ReloadContext): Promise<void> | void;
|
|
137
|
+
serviceStateChange?(context: ServiceStateContext): Promise<void> | void;
|
|
138
|
+
}
|
|
139
|
+
/** A held effect, for an approval surface built on `beforeEffect`. */
|
|
140
|
+
export interface HeldEffect extends EffectHold {
|
|
141
|
+
}
|
package/hooks.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hooks: how a deployment or a plugin adds policy without replacing a module
|
|
3
|
+
* (docs/architecture.md#hooks).
|
|
4
|
+
*
|
|
5
|
+
* The framework sets no policy of its own. Each hook can observe, change or
|
|
6
|
+
* refuse, and refuses in the core's error shape, so the model always reads the
|
|
7
|
+
* same kind of refusal. Permissions, privacy review, budgets and approvals are
|
|
8
|
+
* built from these.
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @4fu/arbor-interfaces - every replaceable interface, and the core's own shapes.
|
|
3
|
+
*
|
|
4
|
+
* No pi type or SQL row crosses an interface; the core only sees
|
|
5
|
+
* its own shapes (docs/architecture.md#interfaces). Each interface ships with
|
|
6
|
+
* a default; replacing a module means implementing its interface and
|
|
7
|
+
* registering it, and nothing else changes.
|
|
8
|
+
*/
|
|
9
|
+
export type { EventRef, WindowRef, NoteId, NoteRef, TaskRef, MessageRef, WorkspaceRef, EnvRef, EnvItemRef, EnvItemName, BlobRef, ExternalRef, Ref, Target, EventKind, LinkKind, MatchKind, } from "./refs.ts";
|
|
10
|
+
export type { BlockValue, Block, BlockKind, BlockFieldSpec, BlockKindSpec, TextTable, } from "./blocks.ts";
|
|
11
|
+
/** Page bounds every read reports (docs/prompting.md). */
|
|
12
|
+
export { DEFAULT_PAGE_LIMIT, MAX_PAGE_LIMIT } from "./refs.ts";
|
|
13
|
+
export type { EventInput, Link, LinkInput, Redaction, Event, ListOptions, Page, EventPage, AroundOptions, SearchOptions, SearchHit, SearchPage, LinksOptions, RelatedItem, LinkPage, TraceOptions, TraceNode, TargetGap, JournalError, } from "./events.ts";
|
|
14
|
+
export type { BlobInput, BlobContent, BlobInfo, BlobStore, Segmenter, Journal, } from "./journal.ts";
|
|
15
|
+
export type { ModelInfo, LoginState, LoginRequest, LoginResult, RenderedPrompt, OpenWindowRequest, WindowLimits, ContinuationInfo, Delivery, WindowSession, WindowEvent, WindowEndReason, WindowOutcome, AgentBackend, DirectToolSpec, ModuleSpec, FunctionSpec, ParameterSpec, ToolCall, ToolResult, } from "./agent.ts";
|
|
16
|
+
export type { WindowState, WindowRuntimeState, TokenUsage, Handoff, BoardLine, Expectation, InputBlock, } from "./windows.ts";
|
|
17
|
+
export type { NoteStatus, Anchor, NoteWriteInput, Note, NoteSummary, NoteBody, NoteRevision, NoteContext, NoteQuery, NoteConflictInfo, ActiveSetBudget, ActiveCandidate, NoteUseKind, NoteUseInput, SnapshotOptions, NotesSnapshot, NoteDelta, NoteDeltaItem, NoteStore, } from "./notes.ts";
|
|
18
|
+
export type { ExecResult, StagedFile, WorkspaceMount, WorkspaceQuota, Workspace, } from "./workspace.ts";
|
|
19
|
+
export type { JudgeMode, JudgeDecisionKind, CandidateWindow, JudgeTask, FilterState, RouteState, ModelTierState, NoticeState, BroadcastState, ActiveSetState, FilterRequest, RouteRequest, ModelTierRequest, NoticeRequest, BroadcastRequest, ActiveSetRequest, JudgeRequest, FilterAnswer, RouteScore, RouteAnswer, ModelTierAnswer, WindowDecision, NoticeAnswer, BroadcastAnswer, ActiveSetAnswer, JudgeAnswer, Judge, JudgeCriteria, } from "./judge.ts";
|
|
20
|
+
export type { OutsideEvent, OutsideMessage, ChannelConnection, SendRequest, SendResult, Unsubscribe, Channel, } from "./channel.ts";
|
|
21
|
+
export type { TaskKind, TaskInput, Task, TaskSource } from "./task.ts";
|
|
22
|
+
export type { EffectKind, Effect, EffectResult, EffectExecutor } from "./effects.ts";
|
|
23
|
+
export type { CallContext, ToolGroup } from "./tools.ts";
|
|
24
|
+
export type { EnvItemKind, EnvItem, EnvDraft, EnvValidation, EnvRevision, EnvDelta, Environment, } from "./environment.ts";
|
|
25
|
+
export type { ServiceState, ServiceSpec, ServiceHandle, ServiceStatus, LogOptions, LogPage, Supervisor, } from "./supervisor.ts";
|
|
26
|
+
export type { QueuedInput, InsertionRequest, InsertionPlan, RateLimitState, AdmissionRequest, AdmissionPlan, SkipPeriod, ScheduledTaskInput, ScheduledTask, ScheduledTaskUpdate, Scheduler, } from "./scheduler.ts";
|
|
27
|
+
export type { HookOutcome, AppendContext, DispatchContext, JudgeContext, WindowStartContext, WindowEndContext, WindowContinueContext, ModelRequestContext, DeliveryContext, ToolCallContext, EffectOutcome, EffectHold, EffectContext, NoteWriteContext, ReloadContext, ServiceStateContext, Hooks, HeldEffect, } from "./hooks.ts";
|
|
28
|
+
export type { PluginAdapters, PromptSection, Plugin, } from "./plugin.ts";
|
|
29
|
+
export type { Settings } from "./settings.ts";
|
package/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @4fu/arbor-interfaces - every replaceable interface, and the core's own shapes.
|
|
3
|
+
*
|
|
4
|
+
* No pi type or SQL row crosses an interface; the core only sees
|
|
5
|
+
* its own shapes (docs/architecture.md#interfaces). Each interface ships with
|
|
6
|
+
* a default; replacing a module means implementing its interface and
|
|
7
|
+
* registering it, and nothing else changes.
|
|
8
|
+
*/
|
|
9
|
+
/** Page bounds every read reports (docs/prompting.md). */
|
|
10
|
+
export { DEFAULT_PAGE_LIMIT, MAX_PAGE_LIMIT } from "./refs.js";
|
package/journal.d.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `Journal` interface: the one append-only record, shared live by every
|
|
3
|
+
* window (docs/journal.md).
|
|
4
|
+
*
|
|
5
|
+
* Rules an implementation must keep:
|
|
6
|
+
*
|
|
7
|
+
* - Append-only. Nothing is edited, nothing is deleted, nothing merges. The one
|
|
8
|
+
* exception is a redaction, which erases content and records that it did.
|
|
9
|
+
* - One global order. `seq` is assigned at append and only grows; watermarks
|
|
10
|
+
* and every comparison use it. `time` is for display only.
|
|
11
|
+
* - An outside message keeps its native id in `external`, with a unique index,
|
|
12
|
+
* so a redelivered message is stored once.
|
|
13
|
+
* - Visible as soon as it is written.
|
|
14
|
+
* - Every refusal is an `ArborError` in the core's shape.
|
|
15
|
+
*/
|
|
16
|
+
import type { AroundOptions, Event, EventInput, EventPage, LinkPage, LinksOptions, ListOptions, SearchOptions, SearchPage, TargetGap, TraceNode, TraceOptions } from "./events.ts";
|
|
17
|
+
import type { BlobRef, EventRef, Ref, Target, WindowRef } from "./refs.ts";
|
|
18
|
+
/** Content a blob store takes. */
|
|
19
|
+
export interface BlobInput {
|
|
20
|
+
data: Uint8Array | string;
|
|
21
|
+
mime?: string;
|
|
22
|
+
}
|
|
23
|
+
/** Content a blob store returns. */
|
|
24
|
+
export interface BlobContent {
|
|
25
|
+
data: Uint8Array;
|
|
26
|
+
mime?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface BlobInfo {
|
|
29
|
+
ref: BlobRef;
|
|
30
|
+
size: number;
|
|
31
|
+
mime?: string;
|
|
32
|
+
time: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Media and files are stored once by content beside the journal; events hold
|
|
36
|
+
* their refs (docs/journal.md#media). The journal never keeps the bytes.
|
|
37
|
+
*/
|
|
38
|
+
export interface BlobStore {
|
|
39
|
+
put(input: BlobInput): Promise<BlobRef>;
|
|
40
|
+
get(ref: BlobRef): Promise<BlobContent | null>;
|
|
41
|
+
has(ref: BlobRef): Promise<boolean>;
|
|
42
|
+
stat(ref: BlobRef): Promise<BlobInfo | null>;
|
|
43
|
+
delete(ref: BlobRef): Promise<void>;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Word segmentation for the word index. The default is jieba's dictionary
|
|
47
|
+
* segmentation when `@4fu/arbor-segmenter-jieba` is installed, and the
|
|
48
|
+
* per-character-and-bigram approximation when it is not
|
|
49
|
+
* (docs/journal.md#search); a deployment replaces either by implementing this
|
|
50
|
+
* and registering it.
|
|
51
|
+
*/
|
|
52
|
+
export interface Segmenter {
|
|
53
|
+
segment(text: string): string[];
|
|
54
|
+
}
|
|
55
|
+
export interface Journal {
|
|
56
|
+
/** Append one event. Assigns `ref` and `seq`; a redelivered `external` id is stored once. */
|
|
57
|
+
append(input: EventInput): Promise<Event>;
|
|
58
|
+
/** Read one event by its ref, or `null`. */
|
|
59
|
+
get(ref: EventRef): Promise<Event | null>;
|
|
60
|
+
/** Read several events by ref, in the order asked for. Missing refs are skipped. */
|
|
61
|
+
getMany(refs: readonly EventRef[]): Promise<Event[]>;
|
|
62
|
+
/** List events chronologically, filtered. */
|
|
63
|
+
list(options?: ListOptions): Promise<EventPage>;
|
|
64
|
+
/** The events around one, in the global order. */
|
|
65
|
+
around(ref: EventRef, options?: AroundOptions): Promise<Event[]>;
|
|
66
|
+
/** Lexical search: exact substring hits first, then word hits, each with its ref and window. */
|
|
67
|
+
search(query: string, options?: SearchOptions): Promise<SearchPage>;
|
|
68
|
+
/** Related items by weight, with the call that pages the rest. */
|
|
69
|
+
links(ref: Ref, options?: LinksOptions): Promise<LinkPage>;
|
|
70
|
+
/** Walk the links back from any ref to where it came from. */
|
|
71
|
+
trace(ref: Ref, options?: TraceOptions): Promise<TraceNode>;
|
|
72
|
+
/** The newest event on a target a window has seen, or `null`. */
|
|
73
|
+
watermark(window: WindowRef, target: Target): Promise<number | null>;
|
|
74
|
+
/** Move a window's watermark forward. Never moves it back. */
|
|
75
|
+
advanceWatermark(window: WindowRef, target: Target, seq: number): Promise<number>;
|
|
76
|
+
/** The targets a window touched that have events it has not seen. */
|
|
77
|
+
targetsBehind(window: WindowRef): Promise<TargetGap[]>;
|
|
78
|
+
/**
|
|
79
|
+
* Erase the content of one event and record that it was erased. Every ref to
|
|
80
|
+
* it keeps working and shows the redaction and the event that made it.
|
|
81
|
+
*/
|
|
82
|
+
redact(ref: EventRef, reason: string): Promise<Event>;
|
|
83
|
+
/** Media and files stored beside the journal. */
|
|
84
|
+
readonly blobs: BlobStore;
|
|
85
|
+
/** Release the underlying store. */
|
|
86
|
+
close(): Promise<void>;
|
|
87
|
+
}
|
package/journal.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `Journal` interface: the one append-only record, shared live by every
|
|
3
|
+
* window (docs/journal.md).
|
|
4
|
+
*
|
|
5
|
+
* Rules an implementation must keep:
|
|
6
|
+
*
|
|
7
|
+
* - Append-only. Nothing is edited, nothing is deleted, nothing merges. The one
|
|
8
|
+
* exception is a redaction, which erases content and records that it did.
|
|
9
|
+
* - One global order. `seq` is assigned at append and only grows; watermarks
|
|
10
|
+
* and every comparison use it. `time` is for display only.
|
|
11
|
+
* - An outside message keeps its native id in `external`, with a unique index,
|
|
12
|
+
* so a redelivered message is stored once.
|
|
13
|
+
* - Visible as soon as it is written.
|
|
14
|
+
* - Every refusal is an `ArborError` in the core's shape.
|
|
15
|
+
*/
|
|
16
|
+
export {};
|