operon-agents 0.1.0-alpha.2 → 0.1.0-alpha.21
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.md +42 -0
- package/dist/app-server/client.js +8 -5
- package/dist/app-server/main.js +1 -1
- package/dist/app-server/params.d.ts +115 -0
- package/dist/app-server/params.js +81 -0
- package/dist/app-server/protocol.d.ts +10 -4
- package/dist/app-server/protocol.js +45 -37
- package/dist/app-server/server.d.ts +0 -1
- package/dist/app-server/server.js +46 -35
- package/dist/core.d.ts +2 -2
- package/dist/core.js +2 -2
- package/dist/cron/cron-expr.js +1 -1
- package/dist/cron/extension.js +2 -2
- package/dist/extensions/index.d.ts +19 -5
- package/dist/extensions/index.js +66 -10
- package/dist/extensions/loader.d.ts +2 -2
- package/dist/extensions/loader.js +23 -15
- package/dist/extensions/manager.d.ts +15 -13
- package/dist/extensions/manager.js +28 -25
- package/dist/extensions/runtime.d.ts +69 -74
- package/dist/extensions/runtime.js +183 -381
- package/dist/extensions/types.d.ts +55 -45
- package/dist/harness.d.ts +339 -180
- package/dist/harness.js +673 -420
- package/dist/index.d.ts +3 -0
- package/dist/index.js +5 -0
- package/dist/internal.d.ts +1 -0
- package/dist/internal.js +1 -0
- package/dist/local.d.ts +25 -8
- package/dist/local.js +103 -33
- package/dist/providers.d.ts +144 -0
- package/dist/providers.js +280 -0
- package/dist/telemetry-posthog.d.ts +88 -0
- package/dist/telemetry-posthog.js +142 -0
- package/dist/telemetry.d.ts +4 -0
- package/dist/telemetry.js +3 -0
- package/dist/workspace-mcp.d.ts +62 -0
- package/dist/workspace-mcp.js +222 -0
- package/package.json +10 -3
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { Environment, EventSink, SteerBus } from "operon-agents-core";
|
|
2
|
+
import type { AgentRecord, HeadlessCommand } from "operon-agents-core";
|
|
3
|
+
import type { AssistantMessage, CapabilityProviderHooks, RunContext, CompactionGate, ChatModel, ConversationContext, Injector, LlmRequest, Message, SessionContext, SessionControls, SessionStore, StepStopReason, TerminalStepStopReason, Tool, ToolPlan, ToolResult, Usage } from "operon-agents-core";
|
|
3
4
|
import type { ExtensionDefinition, ExtensionHost, ExtensionModelRequestResult, ExtensionStepEndResult, ExtensionStepStartResult, ExtensionToolAuthorizeResult, ExtensionToolCallResult, SessionEndReason, SessionStartReason } from "./types.ts";
|
|
4
5
|
/** Shared shape of the loop-hook contexts the dispatch methods are fed from. */
|
|
5
6
|
interface StepOrigin {
|
|
@@ -9,37 +10,48 @@ interface StepOrigin {
|
|
|
9
10
|
readonly signal: AbortSignal;
|
|
10
11
|
readonly model: ChatModel;
|
|
11
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* The session services the extensions capability declares (see `extensionsCapability`). Named
|
|
15
|
+
* here because this is where they are used; the declaration that fills it lives next to the
|
|
16
|
+
* capability, so the two can be checked against each other by eye.
|
|
17
|
+
*/
|
|
18
|
+
export interface ExtensionServices {
|
|
19
|
+
readonly environment: Environment;
|
|
20
|
+
readonly events: EventSink;
|
|
21
|
+
readonly steer: SteerBus;
|
|
22
|
+
readonly controls: SessionControls;
|
|
23
|
+
readonly readLog: () => Promise<readonly AgentRecord[]>;
|
|
24
|
+
readonly store: SessionStore | undefined;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* One extension, running in one session. `extensionCapability` wraps it as that session's
|
|
28
|
+
* capability, so everything around the extension — assembly, hook isolation, attach and detach
|
|
29
|
+
* at a run boundary, its state and records — is the engine's, the same as for any capability.
|
|
30
|
+
* What is left here is the translation the extension API exists for: `api` registrations into
|
|
31
|
+
* capability parts, and the engine's decision points into the extension's event vocabulary.
|
|
32
|
+
*/
|
|
12
33
|
export declare class ExtensionRuntime {
|
|
13
|
-
|
|
34
|
+
readonly definition: ExtensionDefinition;
|
|
14
35
|
private readonly handlers;
|
|
15
36
|
private readonly tools;
|
|
16
|
-
/** Stable reference: `
|
|
37
|
+
/** Stable reference: `extensionCapability` hands this array to the assembler, and `session`
|
|
17
38
|
* (which runs at openSession, before any run assembles) fills it in place. */
|
|
18
39
|
private readonly injectors;
|
|
19
|
-
/** Slash commands
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
/** Extensions whose contributions are currently honored. An id leaves on detach (and on
|
|
31
|
-
* setup failure), which turns every `actions`/`api` closure the extension still holds
|
|
32
|
-
* into a warn-and-noop — a detached extension must not keep steering the session. */
|
|
33
|
-
private readonly live;
|
|
34
|
-
/** Changes wait here until a quiet point: mid-run requests apply at the run's stop
|
|
35
|
-
* boundary, so a turn never sees its toolset change underneath it. */
|
|
36
|
-
private pending;
|
|
37
|
-
/** Serializes flushes so concurrent attach/detach apply strictly in submission order. */
|
|
38
|
-
private flushChain;
|
|
39
|
-
private readonly memoryState;
|
|
40
|
+
/** Slash commands, filled in place by `api.registerCommand` — the capability's `commands`. */
|
|
41
|
+
readonly commands: HeadlessCommand[];
|
|
42
|
+
/** The host-facing control surface published via `api.expose`. */
|
|
43
|
+
private exposed;
|
|
44
|
+
/** `session()`'s cleanup plus every registration, undone in reverse. */
|
|
45
|
+
private teardown;
|
|
46
|
+
/** False until `session` has run, and again once the extension is closed: every `actions` /
|
|
47
|
+
* `api` closure it still holds turns into a warn-and-noop — a detached extension must not
|
|
48
|
+
* keep steering the session. */
|
|
49
|
+
private live;
|
|
50
|
+
/** The session binding: the services the capability DECLARED, plus the session's id/signal. */
|
|
40
51
|
private session;
|
|
41
52
|
private run;
|
|
42
|
-
/** The conversation shard the in-flight decision point belongs to
|
|
53
|
+
/** The conversation shard the in-flight decision point belongs to — the address a
|
|
54
|
+
* `compaction.before` handler is told about. */
|
|
43
55
|
private activeContext;
|
|
44
56
|
/** Snapshot of the last assembled registry, refreshed once per turn by `filterTools`. */
|
|
45
57
|
private allToolNames;
|
|
@@ -48,46 +60,31 @@ export declare class ExtensionRuntime {
|
|
|
48
60
|
private reportingWarning;
|
|
49
61
|
/** Harness reach. Absent when the capability is built standalone (bare Runner / tests). */
|
|
50
62
|
private readonly host;
|
|
51
|
-
/** This session's
|
|
52
|
-
* "skip this extension for this session"; any other value is passed to `setup` as `params`. */
|
|
63
|
+
/** This session's argument for the extension (`createSession({ params: { [id]: … } })`). */
|
|
53
64
|
private readonly params;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
65
|
+
/** What `session.start` reports: `attach` for an extension added to a live session. */
|
|
66
|
+
private readonly startReason;
|
|
67
|
+
constructor(definition: ExtensionDefinition, options?: {
|
|
68
|
+
readonly host?: ExtensionHost;
|
|
69
|
+
readonly params?: unknown;
|
|
70
|
+
readonly startReason?: SessionStartReason;
|
|
71
|
+
});
|
|
72
|
+
get id(): string;
|
|
73
|
+
/** Run `session` and fire `session.start`. Throws when `session` does — the capability is then
|
|
74
|
+
* absent from the session, with nothing it registered left behind. */
|
|
75
|
+
open(services: ExtensionServices, ctx: SessionContext): Promise<void>;
|
|
76
|
+
attachRun(ctx: RunContext): void;
|
|
77
|
+
detachRun(): void;
|
|
78
|
+
/** Fire `session.end` while the handlers are still registered, then unwind everything. */
|
|
58
79
|
close(reason?: SessionEndReason): Promise<void>;
|
|
59
|
-
/**
|
|
60
|
-
*
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
* Rejects on duplicate/empty id or when `setup` throws.
|
|
64
|
-
*/
|
|
65
|
-
attach(definition: ExtensionDefinition): Promise<void>;
|
|
66
|
-
/** Ids of currently attached extensions — the reshape coordinator's affected-set probe. */
|
|
67
|
-
attachedIds(): readonly string[];
|
|
68
|
-
/** Currently attached extensions with what each declared it `uses` — the unload consumer scan. */
|
|
69
|
-
attachedExtensions(): readonly {
|
|
70
|
-
readonly id: string;
|
|
71
|
-
readonly uses: readonly string[];
|
|
72
|
-
}[];
|
|
73
|
-
/** The duck protocol the session's command registry consumes: dynamic commands contributed
|
|
74
|
-
* by attached extensions (`api.registerCommand`). */
|
|
75
|
-
sessionCommands(): readonly HeadlessCommand[];
|
|
76
|
-
/** The control surface `extensionId` published via `api.expose`; undefined when absent
|
|
77
|
-
* (never attached, detached, or nothing exposed). */
|
|
78
|
-
exposedHandle<T = unknown>(extensionId: string): T | undefined;
|
|
79
|
-
/** Remove an extension: its `session.end` fires, then its whole scope is torn down. */
|
|
80
|
-
detach(id: string): Promise<void>;
|
|
81
|
-
private submit;
|
|
82
|
-
private flushPending;
|
|
83
|
-
private drainPending;
|
|
84
|
-
private attachNow;
|
|
85
|
-
private detachNow;
|
|
86
|
-
/** Runs one extension's `setup` and files its scope. Failure ⇒ skipped, contributions undone. */
|
|
80
|
+
/** The control surface published via `api.expose`; undefined when nothing is (or it was
|
|
81
|
+
* disposed, or the extension is closed). */
|
|
82
|
+
exposedHandle<T = unknown>(): T | undefined;
|
|
83
|
+
/** Runs one extension's `session` and files its scope. Failure ⇒ skipped, contributions undone. */
|
|
87
84
|
private setupExtension;
|
|
88
85
|
/**
|
|
89
|
-
* Durable audit trail
|
|
90
|
-
*
|
|
86
|
+
* Durable audit trail of when this extension joined or left the session — written to the
|
|
87
|
+
* session's audit shard, which nothing replays from.
|
|
91
88
|
*/
|
|
92
89
|
private logChange;
|
|
93
90
|
listTools(): readonly Tool[];
|
|
@@ -127,13 +124,17 @@ export declare class ExtensionRuntime {
|
|
|
127
124
|
} | undefined>;
|
|
128
125
|
beforeModelRequest(origin: StepOrigin, request: LlmRequest, context: ConversationContext): Promise<ExtensionModelRequestResult | undefined>;
|
|
129
126
|
/**
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
127
|
+
* The capability's provider hooks — `provider.headers` / `payload` / `response`. The engine
|
|
128
|
+
* composes them into the request with every other capability's, so two extensions rewriting
|
|
129
|
+
* headers both take effect instead of the second replacing the first. They fire once per HTTP
|
|
130
|
+
* ATTEMPT, so a retry re-runs them — the contract tells handlers to be idempotent, and the
|
|
131
|
+
* runtime does not try to dedupe on their behalf.
|
|
135
132
|
*/
|
|
136
|
-
|
|
133
|
+
readonly providerHooks: CapabilityProviderHooks;
|
|
134
|
+
/** Whether any provider-tier handler is registered — the capability omits `provider` otherwise,
|
|
135
|
+
* so a request with no provider-tier extension is left byte-identical. */
|
|
136
|
+
hasProviderHandlers(): boolean;
|
|
137
|
+
private providerContext;
|
|
137
138
|
afterModelResponse(origin: StepOrigin, request: LlmRequest, response: AssistantMessage, context: ConversationContext): Promise<AssistantMessage | undefined>;
|
|
138
139
|
beforeToolCall(origin: StepOrigin, toolName: string, toolCallId: string, tool: Tool | undefined, args: unknown): Promise<ExtensionToolCallResult | undefined>;
|
|
139
140
|
authorizeToolCall(origin: StepOrigin, toolName: string, toolCallId: string, tool: Tool | undefined, args: unknown, plan: ToolPlan): Promise<ExtensionToolAuthorizeResult | undefined>;
|
|
@@ -173,12 +174,6 @@ export declare class ExtensionRuntime {
|
|
|
173
174
|
private viaHost;
|
|
174
175
|
private sessionContext;
|
|
175
176
|
private eventContext;
|
|
176
|
-
/** Open-time record buckets, built ONCE off the session's shared memoized log read — the
|
|
177
|
-
* same single read goal/plan/todo fold from, so `records()` adds zero log traversals. One
|
|
178
|
-
* filter pass buckets every extension's records; ids are colon-free slugs so the
|
|
179
|
-
* "extension:<id>:" prefix parse is unambiguous. */
|
|
180
|
-
private ensureRecordSnapshot;
|
|
181
|
-
private stateFor;
|
|
182
177
|
private handlersFor;
|
|
183
178
|
private invoke;
|
|
184
179
|
private warn;
|