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
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* `ExtensionRuntime` is the façade that hides which physical channel a decision point arrives on;
|
|
25
25
|
* extension authors only ever see one `api.on(...)` table.
|
|
26
26
|
*/
|
|
27
|
-
import type { AgentEvent, AssistantMessage, ChatModel, AgentInput, ContextBreakdown, ConversationContext, Injector, LlmRequest,
|
|
27
|
+
import type { AgentEvent, AssistantMessage, ChatModel, AgentInput, ContextBreakdown, ConversationContext, Injector, LlmRequest, Environment, Message, ModelRuntime, RunResult, SessionSummary, PendingApprovalInterrupt, SessionStore, SteerContent, SteerOptions, SteerOrigin, SteerReceipt, StepStopReason, TerminalStepStopReason, ThinkingLevel, Tool, ToolPlan, ToolResult, ToolResultContent, ToolRunContext, Usage } from "operon-agents-core";
|
|
28
28
|
/** Per-extension key/value state, namespaced into the session store (memory without one). */
|
|
29
29
|
/** A slash command an extension carries (see `ExtensionAPI.registerCommand`). The run
|
|
30
30
|
* receives only the raw argument string — an extension command closes over what it needs. */
|
|
@@ -57,7 +57,7 @@ export interface ExtensionState {
|
|
|
57
57
|
export type ModelProvider = Parameters<ModelRuntime["models"]["setProvider"]>[0];
|
|
58
58
|
/**
|
|
59
59
|
* Operations that exist above the agent loop: other sessions, and the model provider registry.
|
|
60
|
-
* Supplied by `Harness` when it builds
|
|
60
|
+
* Supplied by `Harness` when it builds an extension's capability. This is exactly why the
|
|
61
61
|
* extension runtime lives in `operon-agents` and not in core — core has no concept of "another
|
|
62
62
|
* session", so an interface defined down there would have been half stubs.
|
|
63
63
|
*
|
|
@@ -107,17 +107,18 @@ export interface ExtensionHost {
|
|
|
107
107
|
export interface HarnessSessionHandle {
|
|
108
108
|
readonly id: string;
|
|
109
109
|
prompt(input: AgentInput): Promise<RunResult>;
|
|
110
|
-
steer(input: string):
|
|
111
|
-
followUp(input: string):
|
|
110
|
+
steer(input: string): SteerReceipt;
|
|
111
|
+
followUp(input: string): SteerReceipt | null;
|
|
112
112
|
/**
|
|
113
113
|
* Hand a message to a specific frame in that session — `main` for its root agent,
|
|
114
|
-
* `main/<agentId>` for one of its subagents — carrying your own provenance.
|
|
115
|
-
* frame is running there.
|
|
114
|
+
* `main/<agentId>` for one of its subagents — carrying your own provenance. Undefined when no
|
|
115
|
+
* frame is running there. The receipt's `steerId` (your own, via `options.id`, or minted) is
|
|
116
|
+
* what the recipient's journal carries as `origin.steerId` once the message is consumed.
|
|
116
117
|
*
|
|
117
118
|
* `steer`/`followUp` above can only ever reach the root; this is what lets an extension address
|
|
118
119
|
* an individual subagent, which is what coordination between agents requires.
|
|
119
120
|
*/
|
|
120
|
-
steerTo(address: string, content: string, origin: SteerOrigin):
|
|
121
|
+
steerTo(address: string, content: string, origin: SteerOrigin, options?: SteerOptions): SteerReceipt | undefined;
|
|
121
122
|
cancel(): void;
|
|
122
123
|
close(): Promise<void>;
|
|
123
124
|
}
|
|
@@ -195,7 +196,7 @@ interface ExtensionContextBase {
|
|
|
195
196
|
readonly extensionId: string;
|
|
196
197
|
readonly sessionId: string;
|
|
197
198
|
readonly signal: AbortSignal;
|
|
198
|
-
readonly
|
|
199
|
+
readonly environment: Environment;
|
|
199
200
|
readonly store?: SessionStore;
|
|
200
201
|
readonly state: ExtensionState;
|
|
201
202
|
readonly actions: ExtensionActions;
|
|
@@ -204,18 +205,18 @@ interface ExtensionContextBase {
|
|
|
204
205
|
export interface ExtensionEventContext extends ExtensionContextBase {
|
|
205
206
|
readonly address: string;
|
|
206
207
|
}
|
|
207
|
-
/** Context for session-tier events, which have no active shard. */
|
|
208
|
-
export interface
|
|
208
|
+
/** Context for session-tier events (`session.start` / `session.end`), which have no active shard. */
|
|
209
|
+
export interface ExtensionSessionEventContext extends ExtensionContextBase {
|
|
209
210
|
readonly address?: never;
|
|
210
211
|
}
|
|
211
|
-
/** `attach` = added to a live session via `attachExtension`, after its `
|
|
212
|
+
/** `attach` = added to a live session via `attachExtension`, after its `session` succeeded. */
|
|
212
213
|
export type SessionStartReason = "open" | "resume" | "fork" | "attach";
|
|
213
214
|
/** `detach` = removed from a live session via `detachExtension`; fires before teardown. */
|
|
214
215
|
export type SessionEndReason = "close" | "shutdown" | "detach";
|
|
215
|
-
export interface ExtensionSessionStartEvent extends
|
|
216
|
+
export interface ExtensionSessionStartEvent extends ExtensionSessionEventContext {
|
|
216
217
|
readonly reason: SessionStartReason;
|
|
217
218
|
}
|
|
218
|
-
export interface ExtensionSessionEndEvent extends
|
|
219
|
+
export interface ExtensionSessionEndEvent extends ExtensionSessionEventContext {
|
|
219
220
|
readonly reason: SessionEndReason;
|
|
220
221
|
}
|
|
221
222
|
export interface ExtensionStepStartEvent extends ExtensionEventContext {
|
|
@@ -351,12 +352,10 @@ export interface ExtensionCompactionBeforeResult {
|
|
|
351
352
|
readonly count?: number;
|
|
352
353
|
};
|
|
353
354
|
}
|
|
354
|
-
/**
|
|
355
|
-
*
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
*/
|
|
359
|
-
export type ProviderHeaders = Record<string, string | null>;
|
|
355
|
+
/** Headers a provider request carries (`null` deletes a header) — core's type, the one
|
|
356
|
+
* capability provider hooks use too. */
|
|
357
|
+
export type { ProviderHeaders } from "operon-agents-core";
|
|
358
|
+
import type { ProviderHeaders } from "operon-agents-core";
|
|
360
359
|
/**
|
|
361
360
|
* These three fire BELOW the loop: the runtime folds them into the request's
|
|
362
361
|
* `providerOptions`, and pi-ai calls back from inside its HTTP path. Two consequences the
|
|
@@ -503,23 +502,24 @@ export interface ExtensionAPI {
|
|
|
503
502
|
/**
|
|
504
503
|
* This extension's own journal records, oldest first — the event-sourcing read path.
|
|
505
504
|
* The open-time snapshot rides the session's single shared memoized log read (no extra
|
|
506
|
-
* traversal); records appended this session are included. Fold these in `
|
|
505
|
+
* traversal); records appended this session are included. Fold these in `session` to rebuild
|
|
507
506
|
* sourced state; prefer `state` when a snapshot is all you need.
|
|
508
507
|
*/
|
|
509
508
|
records(): Promise<readonly ExtensionRecordEntry[]>;
|
|
510
509
|
/** Durable per-extension KV (SessionStore-backed) — the same facade handlers get via
|
|
511
|
-
* `ctx.state`, available from `
|
|
510
|
+
* `ctx.state`, available from `session` so state can be loaded before the first run. */
|
|
512
511
|
readonly state: ExtensionState;
|
|
513
|
-
/** The same imperative surface handlers get via `ctx.actions`, usable from `
|
|
512
|
+
/** The same imperative surface handlers get via `ctx.actions`, usable from `session`. */
|
|
514
513
|
readonly actions: ExtensionActions;
|
|
515
514
|
}
|
|
516
515
|
/**
|
|
517
|
-
* What an extension's `
|
|
516
|
+
* What an extension's `harness` half is handed — the harness reach it needs to build a
|
|
518
517
|
* process-shared instance. Deliberately narrow: session creation (a spawn factory's one
|
|
519
|
-
* requirement)
|
|
520
|
-
* service-registration call: the instance IS the
|
|
518
|
+
* requirement), a data directory (the file form's own folder; absent by value) and the handles
|
|
519
|
+
* of the services it declared in `uses`. No service-registration call: the instance IS the
|
|
520
|
+
* return value, registered under the extension's `id`.
|
|
521
521
|
*/
|
|
522
|
-
export interface ExtensionHostContext {
|
|
522
|
+
export interface ExtensionHostContext<TServices extends Readonly<Record<string, unknown>> = Readonly<Record<string, unknown>>> {
|
|
523
523
|
/** Open a brand-new session on this harness — what a spawn factory calls. */
|
|
524
524
|
createSession(options?: {
|
|
525
525
|
readonly title?: string;
|
|
@@ -528,12 +528,20 @@ export interface ExtensionHostContext {
|
|
|
528
528
|
} & Record<string, unknown>): Promise<{
|
|
529
529
|
readonly id: string;
|
|
530
530
|
}>;
|
|
531
|
+
/**
|
|
532
|
+
* Handles to the services named in `uses`, by name — the same handles `session` gets as
|
|
533
|
+
* `ctx.services`, available to the process half too. What lets a file-loaded bundle take its
|
|
534
|
+
* configuration from a host-registered service (`createHarness({ services })`) instead of
|
|
535
|
+
* baking it in: a reload re-runs `harness`, so re-reading the service IS the config update.
|
|
536
|
+
* Method calls resolve the CURRENT provider; the handles expose methods only.
|
|
537
|
+
*/
|
|
538
|
+
readonly services: TServices;
|
|
531
539
|
/** The extension's own folder when it was file-loaded; `undefined` when passed by value.
|
|
532
540
|
* Code only — an update replaces it wholesale. Keep files in `dataDir`. */
|
|
533
541
|
readonly dir?: string;
|
|
534
542
|
/**
|
|
535
543
|
* Where this extension keeps its files: a folder of its own, by id, OUTSIDE the code folder,
|
|
536
|
-
* so replacing the bundle (update) leaves it untouched. Created before `
|
|
544
|
+
* so replacing the bundle (update) leaves it untouched. Created before `harness` runs. Present
|
|
537
545
|
* whenever the harness has a data root — `extensionDir` implies one (`<extensionDir>/.data`);
|
|
538
546
|
* by value it is opt-in (`createHarness({ extensionDataDir })`).
|
|
539
547
|
*/
|
|
@@ -541,13 +549,16 @@ export interface ExtensionHostContext {
|
|
|
541
549
|
warn(message: string): void;
|
|
542
550
|
}
|
|
543
551
|
/**
|
|
544
|
-
* What `
|
|
552
|
+
* What `session` receives besides the API: the handles the framework resolved for this extension
|
|
545
553
|
* in this session. Nothing here is looked up by name from inside the extension — every service
|
|
546
|
-
* it may touch was declared on the definition (`
|
|
554
|
+
* it may touch was declared on the definition (`harness` for its own, `uses` for
|
|
555
|
+
* others') and
|
|
547
556
|
* arrives resolved.
|
|
548
557
|
*/
|
|
549
|
-
export interface
|
|
550
|
-
/** Handle to this extension's own
|
|
558
|
+
export interface ExtensionSessionContext<TShared = unknown, TParams = unknown, TServices extends Readonly<Record<string, unknown>> = Readonly<Record<string, unknown>>> {
|
|
559
|
+
/** Handle to this extension's own shared instance — its `harness` result (one per process) or
|
|
560
|
+
* its `workspace` result (this session's workspace's); `undefined` when it has neither. The
|
|
561
|
+
* session half does not know, and need not know, which tier it lives at. */
|
|
551
562
|
readonly shared: TShared;
|
|
552
563
|
/** This session's per-session argument (`createSession({ params: { [id]: … } })`); `undefined` when none. */
|
|
553
564
|
readonly params: TParams | undefined;
|
|
@@ -561,17 +572,17 @@ export interface ExtensionSetupContext<TShared = unknown, TParams = unknown, TSe
|
|
|
561
572
|
/**
|
|
562
573
|
* An extension: a programmatic participant assembled into a session. One definition, handed to
|
|
563
574
|
* the framework once — by value in `createHarness({ extensions })` or from a file in
|
|
564
|
-
* `extensionDir` — and mounted into every session from then on.
|
|
565
|
-
* optional
|
|
575
|
+
* `extensionDir` — and mounted into every session from then on. Four parts, the first three
|
|
576
|
+
* optional, named for the tier each one runs at (the same three tiers as `createHarness`'s
|
|
577
|
+
* `harness` / `workspace` / `session` hooks):
|
|
566
578
|
*
|
|
567
|
-
* - **`
|
|
568
|
-
* value is registered as a service under this extension's `id
|
|
569
|
-
* receives a stable handle to it as `ctx.shared`.
|
|
570
|
-
* option for an extension with a `create` — only this field.
|
|
579
|
+
* - **`harness` — the process-shared half.** Runs ONCE per harness, not per session. Its return
|
|
580
|
+
* value is registered as a service under this extension's `id` in the harness scope; every
|
|
581
|
+
* session's `session` then receives a stable handle to it as `ctx.shared`.
|
|
571
582
|
* - **`uses` — the services of others it consumes.** Names only; checked when the definition is
|
|
572
|
-
* registered (a consumer must come after its provider) and handed to `
|
|
583
|
+
* registered (a consumer must come after its provider) and handed to `session` resolved as
|
|
573
584
|
* `ctx.services[name]`. There is no lookup by name from inside an extension.
|
|
574
|
-
* - **`
|
|
585
|
+
* - **`session` — the per-session half.** Runs once per session with the resolved context. A
|
|
575
586
|
* session varies it with `createSession({ params: { [id]: … } })` — `ctx.params` — and opts
|
|
576
587
|
* out of it entirely with `false`.
|
|
577
588
|
*
|
|
@@ -583,12 +594,11 @@ export interface ExtensionDefinition<TShared = unknown, TParams = unknown, TServ
|
|
|
583
594
|
readonly id: string;
|
|
584
595
|
/** Per-handler invocation budget. Defaults to 30s for decision points, 1s for observers. */
|
|
585
596
|
readonly timeoutMs?: number;
|
|
586
|
-
/** The process-shared half
|
|
587
|
-
|
|
588
|
-
/** Services this extension consumes, by name — other extensions'
|
|
589
|
-
* `id`s) or host-registered `services`. Resolved into `ctx.services` for `
|
|
597
|
+
/** The process-shared half: once per harness. See above. */
|
|
598
|
+
harness?(host: ExtensionHostContext<TServices>): TShared | Promise<TShared>;
|
|
599
|
+
/** Services this extension consumes, by name — other extensions' shared-half results (their
|
|
600
|
+
* `id`s) or host-registered `services`. Resolved into `ctx.services` for `session`. */
|
|
590
601
|
readonly uses?: readonly (keyof TServices & string)[];
|
|
591
|
-
|
|
602
|
+
session(api: ExtensionAPI, ctx: ExtensionSessionContext<TShared, TParams, TServices>): void | (() => void | Promise<void>) | Promise<void | (() => void | Promise<void>)>;
|
|
592
603
|
}
|
|
593
|
-
export {};
|
|
594
604
|
//# sourceMappingURL=types.d.ts.map
|