@alisio/core 0.1.0-alpha.3
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 +25 -0
- package/dist/application.d.ts +192 -0
- package/dist/application.js +764 -0
- package/dist/config.d.ts +420 -0
- package/dist/config.js +416 -0
- package/dist/core/compaction.d.ts +48 -0
- package/dist/core/compaction.js +206 -0
- package/dist/core/contracts.d.ts +141 -0
- package/dist/core/contracts.js +1 -0
- package/dist/core/registry.d.ts +8 -0
- package/dist/core/registry.js +54 -0
- package/dist/core/runner.d.ts +121 -0
- package/dist/core/runner.js +543 -0
- package/dist/extensions/registry.d.ts +28 -0
- package/dist/extensions/registry.js +58 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +27 -0
- package/dist/integrations/herdr.d.ts +34 -0
- package/dist/integrations/herdr.js +174 -0
- package/dist/mcp/connector.d.ts +63 -0
- package/dist/mcp/connector.js +384 -0
- package/dist/plugins/host.d.ts +164 -0
- package/dist/plugins/host.js +572 -0
- package/dist/providers/openai-compatible.d.ts +14 -0
- package/dist/providers/openai-compatible.js +228 -0
- package/dist/providers/registry.d.ts +35 -0
- package/dist/providers/registry.js +74 -0
- package/dist/providers/routing.d.ts +11 -0
- package/dist/providers/routing.js +41 -0
- package/dist/providers/settings.d.ts +30 -0
- package/dist/providers/settings.js +80 -0
- package/dist/resources/context.d.ts +39 -0
- package/dist/resources/context.js +164 -0
- package/dist/resources/prompts.d.ts +77 -0
- package/dist/resources/prompts.js +182 -0
- package/dist/resources/skills.d.ts +82 -0
- package/dist/resources/skills.js +214 -0
- package/dist/runtime/fs.d.ts +9 -0
- package/dist/runtime/fs.js +73 -0
- package/dist/runtime/modules.d.ts +14 -0
- package/dist/runtime/modules.js +76 -0
- package/dist/runtime/paths.d.ts +4 -0
- package/dist/runtime/paths.js +42 -0
- package/dist/runtime/process.d.ts +16 -0
- package/dist/runtime/process.js +104 -0
- package/dist/runtime/sqlite.d.ts +3 -0
- package/dist/runtime/sqlite.js +85 -0
- package/dist/runtime/store.d.ts +37 -0
- package/dist/runtime/store.js +250 -0
- package/dist/sessions/children.d.ts +55 -0
- package/dist/sessions/children.js +231 -0
- package/dist/startup/index.d.ts +41 -0
- package/dist/startup/index.js +105 -0
- package/dist/startup/mascot.d.ts +6 -0
- package/dist/startup/mascot.js +30 -0
- package/dist/startup/screen.d.ts +18 -0
- package/dist/startup/screen.js +116 -0
- package/dist/startup/text.d.ts +19 -0
- package/dist/startup/text.js +68 -0
- package/dist/tools/execute.d.ts +16 -0
- package/dist/tools/execute.js +96 -0
- package/dist/tools/search.d.ts +69 -0
- package/dist/tools/search.js +232 -0
- package/dist/tools/standard.d.ts +22 -0
- package/dist/tools/standard.js +408 -0
- package/dist/tools/webfetch.d.ts +26 -0
- package/dist/tools/webfetch.js +119 -0
- package/dist/trust.d.ts +34 -0
- package/dist/trust.js +113 -0
- package/package.json +62 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import type { CompactionCheckpoint, Message, ToolCall, ToolResult } from "@alisio/sdk";
|
|
2
|
+
export interface Session {
|
|
3
|
+
id: string;
|
|
4
|
+
workspace: string;
|
|
5
|
+
provider: string;
|
|
6
|
+
model: string;
|
|
7
|
+
/** Child sessions only. */
|
|
8
|
+
parentId?: string;
|
|
9
|
+
depth?: number;
|
|
10
|
+
agent?: string;
|
|
11
|
+
status?: import("@alisio/sdk").SessionStatus;
|
|
12
|
+
title?: string;
|
|
13
|
+
usage?: {
|
|
14
|
+
input: number;
|
|
15
|
+
output: number;
|
|
16
|
+
};
|
|
17
|
+
/** Persisted child spec (narrowing, limits) so resumed runs keep the same restrictions. */
|
|
18
|
+
options?: Record<string, unknown>;
|
|
19
|
+
createdAt?: number;
|
|
20
|
+
updatedAt?: number;
|
|
21
|
+
}
|
|
22
|
+
export interface ChildSessionRecord {
|
|
23
|
+
id?: string;
|
|
24
|
+
parentId: string;
|
|
25
|
+
workspace: string;
|
|
26
|
+
provider: string;
|
|
27
|
+
model: string;
|
|
28
|
+
agent: string;
|
|
29
|
+
title: string;
|
|
30
|
+
depth: number;
|
|
31
|
+
options: Record<string, unknown>;
|
|
32
|
+
}
|
|
33
|
+
export interface SessionStore {
|
|
34
|
+
create(workspace: string, provider: string, model: string): Session;
|
|
35
|
+
get(id: string): Session;
|
|
36
|
+
list(): Session[];
|
|
37
|
+
messages(id: string): Message[];
|
|
38
|
+
append(id: string, message: Message): void;
|
|
39
|
+
createChild(record: ChildSessionRecord): Session;
|
|
40
|
+
children(parentId: string): Session[];
|
|
41
|
+
updateSession(id: string, patch: {
|
|
42
|
+
status?: import("@alisio/sdk").SessionStatus;
|
|
43
|
+
usage?: {
|
|
44
|
+
input: number;
|
|
45
|
+
output: number;
|
|
46
|
+
};
|
|
47
|
+
}): void;
|
|
48
|
+
/** Updates a queued session after its provider/model selector has resolved. */
|
|
49
|
+
updateBinding(id: string, provider: string, model: string): void;
|
|
50
|
+
/** Marks queued/running child sessions not locked by a live process as interrupted. */
|
|
51
|
+
interruptStale(): number;
|
|
52
|
+
/** Record the model used for subsequent turns of the session. */
|
|
53
|
+
setModel(id: string, model: string): void;
|
|
54
|
+
/**
|
|
55
|
+
* Atomically replace the first `replaced` active messages with `summary`, keeping the
|
|
56
|
+
* rest verbatim and in order. Callers must never split a tool call from its results.
|
|
57
|
+
*/
|
|
58
|
+
compact(id: string, replaced: number, summary: Message): void;
|
|
59
|
+
acquire(id: string): void;
|
|
60
|
+
release(id: string): void;
|
|
61
|
+
beginCall(session: string, call: ToolCall): void;
|
|
62
|
+
endCall(session: string, call: ToolCall, result: ToolResult): void;
|
|
63
|
+
reconcile(id: string, acknowledge?: boolean): void;
|
|
64
|
+
event(id: string, runId: string, type: string, data: unknown): void;
|
|
65
|
+
}
|
|
66
|
+
export interface ContextSource {
|
|
67
|
+
/** System instructions; `sessionId` scopes lazily attached nested instructions. */
|
|
68
|
+
instructions(sessionId?: string): Promise<string>;
|
|
69
|
+
/** Instructions newly relevant to paths a tool is about to touch (once per session). */
|
|
70
|
+
beforePaths(paths: string[], sessionId?: string): Promise<string | undefined>;
|
|
71
|
+
}
|
|
72
|
+
export interface Policy {
|
|
73
|
+
write: boolean;
|
|
74
|
+
process: boolean;
|
|
75
|
+
external: boolean;
|
|
76
|
+
}
|
|
77
|
+
export type ApprovalDecision = "once" | "session" | "deny";
|
|
78
|
+
export interface ApprovalRequest {
|
|
79
|
+
call: ToolCall;
|
|
80
|
+
/** Session asking (a child session when delegated). */
|
|
81
|
+
session?: string;
|
|
82
|
+
/** Who is asking, e.g. an agent path such as "general › explore". */
|
|
83
|
+
label?: string;
|
|
84
|
+
effect: "write" | "process" | "external";
|
|
85
|
+
input: Record<string, unknown>;
|
|
86
|
+
signal: AbortSignal;
|
|
87
|
+
}
|
|
88
|
+
/** Optional interactive approval for write/process/external tools not pre-allowed by the Policy. */
|
|
89
|
+
export type ApprovalHandler = (request: ApprovalRequest) => Promise<ApprovalDecision>;
|
|
90
|
+
export interface HookFailure {
|
|
91
|
+
source: string;
|
|
92
|
+
hook: string;
|
|
93
|
+
error: string;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Generic extension points the runner calls. The plugin host implements them with per-hook
|
|
97
|
+
* timeouts and failure isolation; the core never knows what an extension does.
|
|
98
|
+
*/
|
|
99
|
+
export interface RunnerExtensions {
|
|
100
|
+
beforeCompact(input: {
|
|
101
|
+
sessionId: string;
|
|
102
|
+
reason: "manual" | "auto";
|
|
103
|
+
messages: readonly Message[];
|
|
104
|
+
focus?: string;
|
|
105
|
+
}): Promise<{
|
|
106
|
+
instructions: string[];
|
|
107
|
+
/** Field name → description, with the contributing source. */
|
|
108
|
+
fields: Record<string, {
|
|
109
|
+
source: string;
|
|
110
|
+
description: string;
|
|
111
|
+
}>;
|
|
112
|
+
failures: HookFailure[];
|
|
113
|
+
}>;
|
|
114
|
+
afterCompact(input: {
|
|
115
|
+
sessionId: string;
|
|
116
|
+
reason: "manual" | "auto";
|
|
117
|
+
messages: readonly Message[];
|
|
118
|
+
focus?: string;
|
|
119
|
+
model: string;
|
|
120
|
+
replaced: number;
|
|
121
|
+
structured: boolean;
|
|
122
|
+
checkpoint?: CompactionCheckpoint;
|
|
123
|
+
checkpointText: string;
|
|
124
|
+
extracted: Record<string, unknown>;
|
|
125
|
+
}): Promise<{
|
|
126
|
+
inject: string[];
|
|
127
|
+
reports: Record<string, Record<string, unknown>>;
|
|
128
|
+
failures: HookFailure[];
|
|
129
|
+
}>;
|
|
130
|
+
sessionStart(input: {
|
|
131
|
+
sessionId: string;
|
|
132
|
+
model: string;
|
|
133
|
+
workspace: string;
|
|
134
|
+
}): Promise<{
|
|
135
|
+
inject: Array<{
|
|
136
|
+
source: string;
|
|
137
|
+
text: string;
|
|
138
|
+
}>;
|
|
139
|
+
failures: HookFailure[];
|
|
140
|
+
}>;
|
|
141
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ToolDefinition } from "@alisio/sdk";
|
|
2
|
+
export declare class ToolRegistry {
|
|
3
|
+
private entries;
|
|
4
|
+
register(tool: ToolDefinition): () => void;
|
|
5
|
+
list(): ToolDefinition[];
|
|
6
|
+
get(name: string): ToolDefinition;
|
|
7
|
+
parse(name: string, argumentsText: string): Record<string, unknown>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import Ajv from "ajv";
|
|
2
|
+
import Ajv2020 from "ajv/dist/2020.js";
|
|
3
|
+
const ajv2020 = new Ajv2020({ allErrors: true, strict: true });
|
|
4
|
+
const ajv = new Ajv({ allErrors: true, strict: true });
|
|
5
|
+
function rejectReferences(value) {
|
|
6
|
+
if (!value || typeof value !== "object")
|
|
7
|
+
return;
|
|
8
|
+
for (const [k, v] of Object.entries(value)) {
|
|
9
|
+
if (["$ref", "$id", "$async"].includes(k))
|
|
10
|
+
throw new Error(`Schema keyword ${k} is not supported`);
|
|
11
|
+
rejectReferences(v);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export class ToolRegistry {
|
|
15
|
+
entries = new Map();
|
|
16
|
+
register(tool) {
|
|
17
|
+
if (!/^[a-zA-Z0-9_-]{1,64}$/.test(tool.name))
|
|
18
|
+
throw new Error(`Invalid tool name: ${tool.name}`);
|
|
19
|
+
if (this.entries.has(tool.name))
|
|
20
|
+
throw new Error(`Duplicate tool: ${tool.name}`);
|
|
21
|
+
if (tool.inputSchema.type !== "object")
|
|
22
|
+
throw new Error("Tool input schema must be an object");
|
|
23
|
+
rejectReferences(tool.inputSchema);
|
|
24
|
+
const entry = {
|
|
25
|
+
tool,
|
|
26
|
+
validate: (tool.inputSchema.$schema === "https://json-schema.org/draft/2020-12/schema"
|
|
27
|
+
? ajv2020
|
|
28
|
+
: ajv).compile(tool.inputSchema),
|
|
29
|
+
};
|
|
30
|
+
this.entries.set(tool.name, entry);
|
|
31
|
+
return () => {
|
|
32
|
+
if (this.entries.get(tool.name) === entry)
|
|
33
|
+
this.entries.delete(tool.name);
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
list() {
|
|
37
|
+
return [...this.entries.values()].map((x) => x.tool);
|
|
38
|
+
}
|
|
39
|
+
get(name) {
|
|
40
|
+
const e = this.entries.get(name);
|
|
41
|
+
if (!e)
|
|
42
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
43
|
+
return e.tool;
|
|
44
|
+
}
|
|
45
|
+
parse(name, argumentsText) {
|
|
46
|
+
const e = this.entries.get(name);
|
|
47
|
+
if (!e)
|
|
48
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
49
|
+
const value = JSON.parse(argumentsText);
|
|
50
|
+
if (!e.validate(value))
|
|
51
|
+
throw new Error(ajv.errorsText(e.validate.errors));
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { type Attachment, type Message, type ModelProvider, type RunEvent, type ToolDefinition } from "@alisio/sdk";
|
|
2
|
+
import type { ApprovalHandler, ContextSource, Policy, RunnerExtensions, SessionStore } from "./contracts.ts";
|
|
3
|
+
import type { ToolRegistry } from "./registry.ts";
|
|
4
|
+
export interface CompactionSettings {
|
|
5
|
+
/** Compact automatically when context usage crosses `threshold` of a known window. */
|
|
6
|
+
auto?: boolean;
|
|
7
|
+
threshold?: number;
|
|
8
|
+
keepTurns?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface RunnerOptions {
|
|
11
|
+
/** Provider bound to this persisted session. */
|
|
12
|
+
provider: ModelProvider;
|
|
13
|
+
providerFor?: (session: import("./contracts.ts").Session) => Promise<ModelProvider>;
|
|
14
|
+
registry: ToolRegistry;
|
|
15
|
+
store: SessionStore;
|
|
16
|
+
context: ContextSource;
|
|
17
|
+
policy: Policy;
|
|
18
|
+
workspace: string;
|
|
19
|
+
maxTurns?: number;
|
|
20
|
+
timeoutMs?: number;
|
|
21
|
+
maxContextChars?: number;
|
|
22
|
+
maxOutputTokens?: number;
|
|
23
|
+
maxTokens?: number;
|
|
24
|
+
onEvent?: (event: RunEvent) => void;
|
|
25
|
+
readConcurrency?: number;
|
|
26
|
+
/** Context window in tokens for a model, when known. Unknown disables auto compaction. */
|
|
27
|
+
contextWindow?: (model: string) => number | undefined;
|
|
28
|
+
compaction?: CompactionSettings;
|
|
29
|
+
/** When set, write/process tools not allowed by the policy are offered and ask first. */
|
|
30
|
+
approve?: ApprovalHandler;
|
|
31
|
+
/** Generic hooks (implemented by the plugin host) for compaction and session start. */
|
|
32
|
+
extensions?: RunnerExtensions;
|
|
33
|
+
/**
|
|
34
|
+
* Provider-native tool definitions (for example a hosted `web_search` tool) appended to every
|
|
35
|
+
* request's `tools` alongside the registry's function tools. Opt-in, set once for the whole
|
|
36
|
+
* runner; only meaningful for a provider that documents an equivalent server-side tool.
|
|
37
|
+
*/
|
|
38
|
+
nativeTools?: Array<Record<string, unknown>>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Per-run overrides used by embedders and child sessions. Callers must only NARROW: `policy`
|
|
42
|
+
* and `toolFilter` are applied on top of the runner's policy and tools.
|
|
43
|
+
*/
|
|
44
|
+
export interface RunOptions {
|
|
45
|
+
/** What UIs show instead of the prompt (e.g. `/init`). */
|
|
46
|
+
display?: string;
|
|
47
|
+
/** Images attached to this turn's user message, sent as vision content parts. */
|
|
48
|
+
attachments?: Attachment[];
|
|
49
|
+
/** Extra system instructions for this run (e.g. an agent persona). */
|
|
50
|
+
instructions?: string;
|
|
51
|
+
toolFilter?: (tool: ToolDefinition) => boolean;
|
|
52
|
+
policy?: Policy;
|
|
53
|
+
/** Allow interactive approvals for this run (default: when the runner has a handler). */
|
|
54
|
+
approvals?: boolean;
|
|
55
|
+
/** Shown with approval requests, e.g. the agent path of a child session. */
|
|
56
|
+
label?: string;
|
|
57
|
+
workspace?: string;
|
|
58
|
+
context?: ContextSource;
|
|
59
|
+
maxTurns?: number;
|
|
60
|
+
maxTokens?: number;
|
|
61
|
+
timeoutMs?: number;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Default cumulative token budget for one run: several context windows (each turn re-sends the
|
|
65
|
+
* context), clamped; 1M tokens when the window is unknown.
|
|
66
|
+
*/
|
|
67
|
+
export declare function defaultTokenBudget(contextWindow?: number): number;
|
|
68
|
+
export interface CompactionResult {
|
|
69
|
+
replaced: number;
|
|
70
|
+
before: number;
|
|
71
|
+
after: number;
|
|
72
|
+
summary: Extract<Message, {
|
|
73
|
+
role: "user";
|
|
74
|
+
}>;
|
|
75
|
+
}
|
|
76
|
+
export declare class AgentRunner {
|
|
77
|
+
private options;
|
|
78
|
+
/** Sessions with an active run or compaction (one at a time per session). */
|
|
79
|
+
private active;
|
|
80
|
+
/** Messages queued for a session's next turn (e.g. input for a running child). */
|
|
81
|
+
private inbox;
|
|
82
|
+
/** Last provider-reported context size per session and the history length it covered. */
|
|
83
|
+
private reported;
|
|
84
|
+
constructor(options: RunnerOptions);
|
|
85
|
+
/** Current capability policy (may widen when the user approves an effect for the session). */
|
|
86
|
+
get policy(): Readonly<Policy>;
|
|
87
|
+
/** Whether write/process tools can be approved interactively. */
|
|
88
|
+
get approvals(): boolean;
|
|
89
|
+
private emitter;
|
|
90
|
+
/** Tools offered to the model under the current policy (and optional run narrowing). */
|
|
91
|
+
availableTools(run?: RunOptions): ToolDefinition[];
|
|
92
|
+
/** Abort signal of the session's active run, if any (used to cascade cancellation). */
|
|
93
|
+
signal(sessionId: string): AbortSignal | undefined;
|
|
94
|
+
isRunning(sessionId: string): boolean;
|
|
95
|
+
/** Aborts the active run (or compaction) of a session. */
|
|
96
|
+
abort(sessionId: string, reason?: unknown): boolean;
|
|
97
|
+
/** Queues text as a user message for the session's next turn (or next run when idle). */
|
|
98
|
+
enqueue(sessionId: string, text: string): void;
|
|
99
|
+
private drain;
|
|
100
|
+
private claim;
|
|
101
|
+
private toolsText;
|
|
102
|
+
/** Estimated tokens the next request of a session would send. */
|
|
103
|
+
estimateContext(sessionId: string): Promise<number>;
|
|
104
|
+
/** Change the model used by subsequent turns of a session; recorded in the store. */
|
|
105
|
+
setModel(sessionId: string, model: string): void;
|
|
106
|
+
/** Manually compact a session outside a run. */
|
|
107
|
+
compact(sessionId: string, request?: {
|
|
108
|
+
focus?: string;
|
|
109
|
+
signal?: AbortSignal;
|
|
110
|
+
}): Promise<CompactionResult | undefined>;
|
|
111
|
+
private compactLocked;
|
|
112
|
+
run(sessionId: string, prompt: string, signal?: AbortSignal, options?: RunOptions): Promise<{
|
|
113
|
+
sessionId: string;
|
|
114
|
+
text: string;
|
|
115
|
+
status: string;
|
|
116
|
+
usage: {
|
|
117
|
+
input: number;
|
|
118
|
+
output: number;
|
|
119
|
+
};
|
|
120
|
+
}>;
|
|
121
|
+
}
|