@schlenkr/ragents 0.1.6 → 0.1.8
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/apps/server/src/chat-handler.ts +2 -0
- package/apps/server/src/config.ts +6 -0
- package/apps/server/src/host-api.json +1 -0
- package/apps/server/src/layout.ts +0 -15
- package/apps/server/src/plugin-support/agent-tool.ts +2 -3
- package/apps/server/src/plugin-support/plugin-folder.ts +2 -1
- package/apps/server/src/provider.ts +34 -11
- package/apps/server/src/ragents/actor-chat-history.ts +1 -0
- package/apps/server/src/ragents/engine.ts +23 -24
- package/apps/server/src/ragents/journal-chat-events.ts +2 -0
- package/apps/server/src/ragents/run-owner.ts +3 -2
- package/apps/server/src/ragents/session.ts +3 -3
- package/apps/server/src/run-preparation.ts +14 -18
- package/apps/server/src/run-transfer.ts +65 -4
- package/apps/server/src/settings.ts +2 -4
- package/apps/web/dist/assets/{highlighted-body-KPVGNVTW-B9qYBARS.js → highlighted-body-KPVGNVTW-xXXhTDbh.js} +1 -1
- package/apps/web/dist/assets/{main-BCjvD2Hh.js → main-C7JeZFjs.js} +1 -1
- package/apps/web/dist/assets/{mermaid-HWGCJPDP-CvYYFK_n.js → mermaid-HWGCJPDP-DfsU5ofC.js} +69 -69
- package/apps/web/dist/assets/{runPanel-CG7kRMJh.js → runPanel-ZT6TPDLM.js} +1 -1
- package/apps/web/dist/help/guide-clients.html +13 -4
- package/apps/web/dist/help/guide-clients.md +14 -4
- package/apps/web/dist/help/guide-distributed.html +8 -3
- package/apps/web/dist/help/guide-distributed.md +8 -3
- package/apps/web/dist/help/guide-runtime.html +18 -12
- package/apps/web/dist/help/guide-runtime.md +19 -12
- package/apps/web/dist/help/mini-app.css +23 -3
- package/apps/web/dist/host-web.json +4 -4
- package/apps/web/dist/index.html +2 -2
- package/apps/web/dist/run-panel.html +2 -2
- package/apps/web/src/SessionList.tsx +16 -8
- package/apps/web/src/StartTiles.tsx +1 -1
- package/apps/web/src/api.ts +2 -0
- package/apps/web/src/panel/PanelPage.tsx +1 -1
- package/apps/web/src/panel/RunLine.tsx +4 -2
- package/apps/web/src/panel/contract.ts +2 -0
- package/bundles/ragents.activity/ragents-bundle.json +1 -1
- package/bundles/ragents.actor-programs/ragents-bundle.json +1 -1
- package/bundles/ragents.ask/ragents-bundle.json +1 -1
- package/bundles/ragents.browser/ragents-bundle.json +1 -1
- package/bundles/ragents.documents/ragents-bundle.json +1 -1
- package/bundles/ragents.lsp-fsharp/ragents-bundle.json +1 -1
- package/bundles/ragents.lsp-roslyn/ragents-bundle.json +1 -1
- package/bundles/ragents.lsp-typescript/ragents-bundle.json +1 -1
- package/bundles/ragents.model-relay/ragents-bundle.json +1 -1
- package/bundles/ragents.orchestration/ragents-bundle.json +1 -1
- package/bundles/ragents.overseer/ragents-bundle.json +1 -1
- package/bundles/ragents.processes/ragents-bundle.json +1 -1
- package/bundles/ragents.product/ragents-bundle.json +1 -1
- package/bundles/ragents.profile-distribution/ragents-bundle.json +1 -1
- package/bundles/ragents.reference/ragents-bundle.json +2 -2
- package/bundles/ragents.reference/run-scripts/learning-afternoon/tests/program.test.ts +1 -1
- package/bundles/ragents.reference/run-scripts/word-game/tests/program.test.ts +3 -3
- package/bundles/ragents.todo/ragents-bundle.json +1 -1
- package/bundles/ragents.transcript/ragents-bundle.json +1 -1
- package/bundles/ragents.watch/ragents-bundle.json +1 -1
- package/bundles/ragents.workspace/ragents-bundle.json +1 -1
- package/package.json +2 -2
- package/packages/agent/dist/core/agent-settings.d.ts +2 -2
- package/packages/agent/dist/core/compaction/compaction.d.ts +16 -50
- package/packages/agent/dist/core/context-log.d.ts +25 -0
- package/packages/agent/dist/core/messages.d.ts +3 -10
- package/packages/agent/dist/core/tool-definition.d.ts +17 -0
- package/packages/agent/dist/core/tools/bash.d.ts +2 -7
- package/packages/agent/dist/core/tools/edit.d.ts +1 -1
- package/packages/agent/dist/core/tools/read.d.ts +1 -1
- package/packages/agent/dist/core/tools/write.d.ts +1 -1
- package/packages/agent/dist/index.d.ts +7 -8
- package/packages/agent/dist/loop/agent.d.ts +2 -6
- package/packages/agent/package.json +1 -1
- package/packages/agent/src/core/agent-settings.ts +2 -2
- package/packages/agent/src/core/compaction/compaction.ts +49 -175
- package/packages/agent/src/core/context-log.ts +49 -0
- package/packages/agent/src/core/messages.ts +5 -11
- package/packages/agent/src/core/tool-definition.ts +29 -0
- package/packages/agent/src/core/tools/bash.ts +2 -9
- package/packages/agent/src/core/tools/edit.ts +2 -11
- package/packages/agent/src/core/tools/read.ts +3 -18
- package/packages/agent/src/core/tools/write.ts +1 -5
- package/packages/agent/src/index.ts +28 -14
- package/packages/agent/src/loop/agent-loop.ts +1 -2
- package/packages/agent/src/loop/agent.ts +8 -2
- package/packages/ai/dist/api/ai-sdk.d.ts +2 -0
- package/packages/ai/dist/types.d.ts +2 -0
- package/packages/ai/src/api/ai-sdk-messages.ts +15 -10
- package/packages/ai/src/api/ai-sdk.ts +11 -0
- package/packages/ai/src/api/transform-messages.ts +1 -1
- package/packages/ai/src/types.ts +2 -0
- package/packages/ai/src/utils/retry.ts +14 -0
- package/packages/ragents/src/agents/actor-input.ts +15 -0
- package/packages/ragents/src/agents/model-context.ts +360 -0
- package/packages/ragents/src/agents/plugins.ts +5 -0
- package/packages/ragents/src/agents/scheduler.ts +3 -7
- package/packages/ragents/src/agents/tools.ts +2 -2
- package/packages/ragents/src/agents/toolset.ts +47 -20
- package/packages/ragents/src/agents/workspaces.ts +0 -6
- package/packages/ragents/src/domain/event-semantics.ts +51 -0
- package/packages/ragents/src/domain/event-validation.ts +166 -0
- package/packages/ragents/src/domain/events.ts +72 -0
- package/packages/ragents/src/domain/model.ts +4 -2
- package/packages/ragents/src/domain/projection.ts +9 -0
- package/packages/ragents/src/domain/tool-result-text.ts +9 -0
- package/packages/ragents/src/drivers/agent-hooks.ts +25 -38
- package/packages/ragents/src/drivers/agent-runtime.ts +118 -933
- package/packages/ragents/src/drivers/agent-turn.ts +735 -0
- package/packages/ragents/src/drivers/agent.ts +9 -7
- package/packages/ragents/src/drivers/skill-preload.ts +53 -63
- package/packages/ragents/src/drivers/types.ts +21 -5
- package/packages/ragents/src/index.ts +8 -6
- package/packages/ragents/src/plugin-host.ts +60 -13
- package/packages/ragents/src/plugin-types.ts +7 -2
- package/packages/ragents/src/runtime/decisions/actors.ts +10 -0
- package/packages/ragents/src/runtime/decisions/turns.ts +66 -7
- package/packages/ragents/src/runtime/journal-storage.ts +7 -4
- package/packages/ragents/src/runtime/journal.ts +35 -0
- package/packages/ragents/src/runtime/orchestration.ts +140 -9
- package/packages/workspace-executor/src/sandbox-tools.ts +10 -11
- package/plugins/ragents.reference/run-scripts/learning-afternoon/tests/program.test.ts +1 -1
- package/plugins/ragents.reference/run-scripts/word-game/tests/program.test.ts +3 -3
- package/scripts/agent/journal.ts +5 -3
- package/scripts/package/publish-package.ts +4 -3
- package/packages/agent/dist/core/agent-session-runtime.d.ts +0 -33
- package/packages/agent/dist/core/agent-session-services.d.ts +0 -35
- package/packages/agent/dist/core/agent-session.d.ts +0 -234
- package/packages/agent/dist/core/auth-guidance.d.ts +0 -4
- package/packages/agent/dist/core/defaults.d.ts +0 -3
- package/packages/agent/dist/core/extensions/index.d.ts +0 -11
- package/packages/agent/dist/core/extensions/loader.d.ts +0 -12
- package/packages/agent/dist/core/extensions/runner.d.ts +0 -39
- package/packages/agent/dist/core/extensions/types.d.ts +0 -156
- package/packages/agent/dist/core/extensions/wrapper.d.ts +0 -12
- package/packages/agent/dist/core/resource-loader.d.ts +0 -39
- package/packages/agent/dist/core/sdk.d.ts +0 -38
- package/packages/agent/dist/core/session-manager.d.ts +0 -189
- package/packages/agent/dist/core/source-info.d.ts +0 -16
- package/packages/agent/dist/core/system-prompt.d.ts +0 -21
- package/packages/agent/src/core/agent-session-runtime.ts +0 -94
- package/packages/agent/src/core/agent-session-services.ts +0 -74
- package/packages/agent/src/core/agent-session.ts +0 -1108
- package/packages/agent/src/core/auth-guidance.ts +0 -14
- package/packages/agent/src/core/defaults.ts +0 -3
- package/packages/agent/src/core/extensions/index.ts +0 -38
- package/packages/agent/src/core/extensions/loader.ts +0 -125
- package/packages/agent/src/core/extensions/runner.ts +0 -211
- package/packages/agent/src/core/extensions/types.ts +0 -197
- package/packages/agent/src/core/extensions/wrapper.ts +0 -24
- package/packages/agent/src/core/resource-loader.ts +0 -142
- package/packages/agent/src/core/sdk.ts +0 -123
- package/packages/agent/src/core/session-manager.ts +0 -743
- package/packages/agent/src/core/source-info.ts +0 -28
- package/packages/agent/src/core/system-prompt.ts +0 -108
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
const UNKNOWN_PROVIDER = "unknown";
|
|
2
|
-
|
|
3
|
-
export function getProviderLoginHelp(): string {
|
|
4
|
-
return "Kein Zugang zu einem Provider. Der Schlüssel kommt aus der Konfiguration des Profils.";
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export function formatNoModelSelectedMessage(): string {
|
|
8
|
-
return `No model selected.\n\n${getProviderLoginHelp()}\n\nThen use /model to select a model.`;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function formatNoApiKeyFoundMessage(provider: string): string {
|
|
12
|
-
const providerDisplay = provider === UNKNOWN_PROVIDER ? "the selected model" : provider;
|
|
13
|
-
return `No API key found for ${providerDisplay}.\n\n${getProviderLoginHelp()}`;
|
|
14
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Extension system for agent hooks and custom tools.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export type { SourceInfo } from "../source-info.ts";
|
|
6
|
-
export { createExtensionRuntime, loadExtensionFromFactory } from "./loader.ts";
|
|
7
|
-
export type { ExtensionContextSource, ExtensionErrorListener } from "./runner.ts";
|
|
8
|
-
export { ExtensionRunner, STALE_EXTENSION_MESSAGE } from "./runner.ts";
|
|
9
|
-
export type {
|
|
10
|
-
AgentToolResult,
|
|
11
|
-
AgentToolUpdateCallback,
|
|
12
|
-
BeforeAgentStartEvent,
|
|
13
|
-
BeforeAgentStartEventResult,
|
|
14
|
-
BuildSystemPromptOptions,
|
|
15
|
-
ContextEvent,
|
|
16
|
-
ContextEventResult,
|
|
17
|
-
Extension,
|
|
18
|
-
ExtensionActions,
|
|
19
|
-
ExtensionAPI,
|
|
20
|
-
ExtensionContext,
|
|
21
|
-
ExtensionError,
|
|
22
|
-
ExtensionEvent,
|
|
23
|
-
ExtensionFactory,
|
|
24
|
-
ExtensionFactoryContext,
|
|
25
|
-
ExtensionFactorySettlementObserver,
|
|
26
|
-
ExtensionHandler,
|
|
27
|
-
ExtensionRuntime,
|
|
28
|
-
InlineExtension,
|
|
29
|
-
LoadExtensionsResult,
|
|
30
|
-
RegisteredTool,
|
|
31
|
-
ToolDefinition,
|
|
32
|
-
ToolExecutionMode,
|
|
33
|
-
ToolInfo,
|
|
34
|
-
ToolResultEvent,
|
|
35
|
-
ToolResultEventResult,
|
|
36
|
-
} from "./types.ts";
|
|
37
|
-
export { defineTool } from "./types.ts";
|
|
38
|
-
export { wrapRegisteredTools } from "./wrapper.ts";
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Extension loader - creates extensions from inline factories.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { createSyntheticSourceInfo } from "../source-info.ts";
|
|
6
|
-
import type {
|
|
7
|
-
Extension,
|
|
8
|
-
ExtensionAPI,
|
|
9
|
-
ExtensionFactory,
|
|
10
|
-
ExtensionFactorySettlementObserver,
|
|
11
|
-
ExtensionRuntime,
|
|
12
|
-
ToolDefinition,
|
|
13
|
-
} from "./types.ts";
|
|
14
|
-
|
|
15
|
-
type HandlerFn = (...args: unknown[]) => Promise<unknown>;
|
|
16
|
-
|
|
17
|
-
function abortReason(signal: AbortSignal): Error {
|
|
18
|
-
return signal.reason instanceof Error ? signal.reason : new Error("Extension creation was aborted.");
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function awaitWithSignal<T>(operation: Promise<T>, signal: AbortSignal | undefined): Promise<T> {
|
|
22
|
-
if (!signal) {
|
|
23
|
-
return operation;
|
|
24
|
-
}
|
|
25
|
-
if (signal.aborted) {
|
|
26
|
-
return Promise.reject(abortReason(signal));
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return new Promise<T>((resolve, reject) => {
|
|
30
|
-
const abort = () => reject(abortReason(signal));
|
|
31
|
-
signal.addEventListener("abort", abort, { once: true });
|
|
32
|
-
operation.then(resolve, reject).finally(() => signal.removeEventListener("abort", abort));
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Create a runtime with throwing stubs for action methods.
|
|
38
|
-
* Runner.bindCore() replaces these with real implementations.
|
|
39
|
-
*/
|
|
40
|
-
export function createExtensionRuntime(): ExtensionRuntime {
|
|
41
|
-
const notInitialized = () => {
|
|
42
|
-
throw new Error("Extension runtime not initialized. Action methods cannot be called during extension loading.");
|
|
43
|
-
};
|
|
44
|
-
const state: { staleMessage?: string } = {};
|
|
45
|
-
|
|
46
|
-
return {
|
|
47
|
-
appendEntry: notInitialized,
|
|
48
|
-
getAllTools: notInitialized,
|
|
49
|
-
setActiveTools: notInitialized,
|
|
50
|
-
// registerTool() is valid during extension load; refresh is only needed post-bind.
|
|
51
|
-
refreshTools: () => {},
|
|
52
|
-
assertActive: () => {
|
|
53
|
-
if (state.staleMessage) {
|
|
54
|
-
throw new Error(state.staleMessage);
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
invalidate: (message) => {
|
|
58
|
-
state.staleMessage ??= message ?? "This extension is stale.";
|
|
59
|
-
},
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/** Registration methods write to the extension object, action methods delegate to the shared runtime. */
|
|
64
|
-
function createExtensionAPI(extension: Extension, runtime: ExtensionRuntime): ExtensionAPI {
|
|
65
|
-
return {
|
|
66
|
-
on(event: string, handler: HandlerFn): void {
|
|
67
|
-
runtime.assertActive();
|
|
68
|
-
const list = extension.handlers.get(event) ?? [];
|
|
69
|
-
list.push(handler);
|
|
70
|
-
extension.handlers.set(event, list);
|
|
71
|
-
},
|
|
72
|
-
|
|
73
|
-
registerTool(tool: ToolDefinition): void {
|
|
74
|
-
runtime.assertActive();
|
|
75
|
-
extension.tools.set(tool.name, {
|
|
76
|
-
definition: tool,
|
|
77
|
-
sourceInfo: extension.sourceInfo,
|
|
78
|
-
});
|
|
79
|
-
runtime.refreshTools();
|
|
80
|
-
},
|
|
81
|
-
|
|
82
|
-
appendEntry(customType: string, data?: unknown): void {
|
|
83
|
-
runtime.assertActive();
|
|
84
|
-
runtime.appendEntry(customType, data);
|
|
85
|
-
},
|
|
86
|
-
|
|
87
|
-
getAllTools() {
|
|
88
|
-
runtime.assertActive();
|
|
89
|
-
return runtime.getAllTools();
|
|
90
|
-
},
|
|
91
|
-
|
|
92
|
-
setActiveTools(toolNames: string[]): void {
|
|
93
|
-
runtime.assertActive();
|
|
94
|
-
runtime.setActiveTools(toolNames);
|
|
95
|
-
},
|
|
96
|
-
} as ExtensionAPI;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/** Create an Extension from an inline factory function. */
|
|
100
|
-
export async function loadExtensionFromFactory(
|
|
101
|
-
factory: ExtensionFactory,
|
|
102
|
-
runtime: ExtensionRuntime,
|
|
103
|
-
extensionPath: string,
|
|
104
|
-
signal?: AbortSignal,
|
|
105
|
-
onFactorySettlement?: ExtensionFactorySettlementObserver,
|
|
106
|
-
): Promise<Extension> {
|
|
107
|
-
const extension: Extension = {
|
|
108
|
-
path: extensionPath,
|
|
109
|
-
sourceInfo: createSyntheticSourceInfo(extensionPath, { source: "inline" }),
|
|
110
|
-
handlers: new Map(),
|
|
111
|
-
tools: new Map(),
|
|
112
|
-
};
|
|
113
|
-
const api = createExtensionAPI(extension, runtime);
|
|
114
|
-
try {
|
|
115
|
-
const factorySettlement = Promise.resolve(factory(api, { signal: signal ?? new AbortController().signal }));
|
|
116
|
-
onFactorySettlement?.(factorySettlement);
|
|
117
|
-
await awaitWithSignal(factorySettlement, signal);
|
|
118
|
-
} catch (error) {
|
|
119
|
-
if (signal?.aborted) {
|
|
120
|
-
runtime.invalidate("Extension creation was aborted.");
|
|
121
|
-
}
|
|
122
|
-
throw error;
|
|
123
|
-
}
|
|
124
|
-
return extension;
|
|
125
|
-
}
|
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Extension runner - executes extension handlers against one agent session.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import type { AgentMessage } from "../../loop/index.ts";
|
|
6
|
-
import type { Model, UserAttachment } from "@ragents/ai";
|
|
7
|
-
import type { SessionManager } from "../session-manager.ts";
|
|
8
|
-
import type { BuildSystemPromptOptions } from "../system-prompt.ts";
|
|
9
|
-
import type {
|
|
10
|
-
BeforeAgentStartEvent,
|
|
11
|
-
BeforeAgentStartEventResult,
|
|
12
|
-
ContextEvent,
|
|
13
|
-
ContextEventResult,
|
|
14
|
-
Extension,
|
|
15
|
-
ExtensionActions,
|
|
16
|
-
ExtensionContext,
|
|
17
|
-
ExtensionError,
|
|
18
|
-
ExtensionRuntime,
|
|
19
|
-
RegisteredTool,
|
|
20
|
-
ToolResultEvent,
|
|
21
|
-
ToolResultEventResult,
|
|
22
|
-
} from "./types.ts";
|
|
23
|
-
|
|
24
|
-
export type ExtensionErrorListener = (error: ExtensionError) => void;
|
|
25
|
-
|
|
26
|
-
/** What the runner reads from its session when it builds a handler context. */
|
|
27
|
-
export interface ExtensionContextSource {
|
|
28
|
-
getModel: () => Model<any> | undefined;
|
|
29
|
-
getSignal: () => AbortSignal | undefined;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export const STALE_EXTENSION_MESSAGE = "This extension is stale: its agent session was disposed.";
|
|
33
|
-
|
|
34
|
-
export class ExtensionRunner {
|
|
35
|
-
private readonly extensions: Extension[];
|
|
36
|
-
private readonly runtime: ExtensionRuntime;
|
|
37
|
-
private readonly sessionManager: SessionManager;
|
|
38
|
-
private readonly errorListeners: Set<ExtensionErrorListener> = new Set();
|
|
39
|
-
private contextSource: ExtensionContextSource = { getModel: () => undefined, getSignal: () => undefined };
|
|
40
|
-
private staleMessage: string | undefined;
|
|
41
|
-
|
|
42
|
-
constructor(extensions: Extension[], runtime: ExtensionRuntime, sessionManager: SessionManager) {
|
|
43
|
-
this.extensions = extensions;
|
|
44
|
-
this.runtime = runtime;
|
|
45
|
-
this.sessionManager = sessionManager;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
bindCore(actions: ExtensionActions, contextSource: ExtensionContextSource): void {
|
|
49
|
-
this.runtime.appendEntry = actions.appendEntry;
|
|
50
|
-
this.runtime.getAllTools = actions.getAllTools;
|
|
51
|
-
this.runtime.setActiveTools = actions.setActiveTools;
|
|
52
|
-
this.runtime.refreshTools = actions.refreshTools;
|
|
53
|
-
this.contextSource = contextSource;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/** Get all registered tools from all extensions (first registration per name wins). */
|
|
57
|
-
getAllRegisteredTools(): RegisteredTool[] {
|
|
58
|
-
const toolsByName = new Map<string, RegisteredTool>();
|
|
59
|
-
for (const ext of this.extensions) {
|
|
60
|
-
for (const tool of ext.tools.values()) {
|
|
61
|
-
if (!toolsByName.has(tool.definition.name)) {
|
|
62
|
-
toolsByName.set(tool.definition.name, tool);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
return Array.from(toolsByName.values());
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
invalidate(message = STALE_EXTENSION_MESSAGE): void {
|
|
70
|
-
if (!this.staleMessage) {
|
|
71
|
-
this.staleMessage = message;
|
|
72
|
-
this.runtime.invalidate(message);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
private assertActive(): void {
|
|
77
|
-
if (this.staleMessage) {
|
|
78
|
-
throw new Error(this.staleMessage);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
onError(listener: ExtensionErrorListener): () => void {
|
|
83
|
-
this.errorListeners.add(listener);
|
|
84
|
-
return () => this.errorListeners.delete(listener);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
private emitError(ext: Extension, event: string, err: unknown): void {
|
|
88
|
-
const error: ExtensionError = {
|
|
89
|
-
extensionPath: ext.path,
|
|
90
|
-
event,
|
|
91
|
-
error: err instanceof Error ? err.message : String(err),
|
|
92
|
-
stack: err instanceof Error ? err.stack : undefined,
|
|
93
|
-
};
|
|
94
|
-
for (const listener of this.errorListeners) {
|
|
95
|
-
listener(error);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
hasHandlers(eventType: string): boolean {
|
|
100
|
-
return this.extensions.some((ext) => (ext.handlers.get(eventType)?.length ?? 0) > 0);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/** Context values are resolved at call time, so a disposed session is detected on every access. */
|
|
104
|
-
createContext(): ExtensionContext {
|
|
105
|
-
const runner = this;
|
|
106
|
-
return {
|
|
107
|
-
get sessionManager() {
|
|
108
|
-
runner.assertActive();
|
|
109
|
-
return runner.sessionManager;
|
|
110
|
-
},
|
|
111
|
-
get model() {
|
|
112
|
-
runner.assertActive();
|
|
113
|
-
return runner.contextSource.getModel();
|
|
114
|
-
},
|
|
115
|
-
get signal() {
|
|
116
|
-
runner.assertActive();
|
|
117
|
-
return runner.contextSource.getSignal();
|
|
118
|
-
},
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
async emitToolResult(event: ToolResultEvent): Promise<ToolResultEventResult | undefined> {
|
|
123
|
-
const ctx = this.createContext();
|
|
124
|
-
const currentEvent: ToolResultEvent = { ...event };
|
|
125
|
-
let modified = false;
|
|
126
|
-
|
|
127
|
-
for (const ext of this.extensions) {
|
|
128
|
-
for (const handler of ext.handlers.get("tool_result") ?? []) {
|
|
129
|
-
try {
|
|
130
|
-
const handlerResult = (await handler(currentEvent, ctx)) as ToolResultEventResult | undefined;
|
|
131
|
-
if (!handlerResult) continue;
|
|
132
|
-
|
|
133
|
-
if (handlerResult.content !== undefined) {
|
|
134
|
-
currentEvent.content = handlerResult.content;
|
|
135
|
-
modified = true;
|
|
136
|
-
}
|
|
137
|
-
if (handlerResult.details !== undefined) {
|
|
138
|
-
currentEvent.details = handlerResult.details;
|
|
139
|
-
modified = true;
|
|
140
|
-
}
|
|
141
|
-
if (handlerResult.isError !== undefined) {
|
|
142
|
-
currentEvent.isError = handlerResult.isError;
|
|
143
|
-
modified = true;
|
|
144
|
-
}
|
|
145
|
-
} catch (err) {
|
|
146
|
-
this.emitError(ext, "tool_result", err);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
return modified
|
|
152
|
-
? { content: currentEvent.content, details: currentEvent.details, isError: currentEvent.isError }
|
|
153
|
-
: undefined;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
async emitContext(messages: AgentMessage[]): Promise<AgentMessage[]> {
|
|
157
|
-
const ctx = this.createContext();
|
|
158
|
-
let currentMessages = structuredClone(messages);
|
|
159
|
-
|
|
160
|
-
for (const ext of this.extensions) {
|
|
161
|
-
for (const handler of ext.handlers.get("context") ?? []) {
|
|
162
|
-
try {
|
|
163
|
-
const event: ContextEvent = { type: "context", messages: currentMessages };
|
|
164
|
-
const handlerResult = (await handler(event, ctx)) as ContextEventResult | undefined;
|
|
165
|
-
if (handlerResult?.messages) {
|
|
166
|
-
currentMessages = handlerResult.messages;
|
|
167
|
-
}
|
|
168
|
-
} catch (err) {
|
|
169
|
-
this.emitError(ext, "context", err);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
return currentMessages;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/** Chains the system prompt through all before_agent_start handlers; undefined when none changed it. */
|
|
178
|
-
async emitBeforeAgentStart(
|
|
179
|
-
prompt: string,
|
|
180
|
-
systemPrompt: string,
|
|
181
|
-
systemPromptOptions: BuildSystemPromptOptions,
|
|
182
|
-
attachments?: UserAttachment[],
|
|
183
|
-
): Promise<string | undefined> {
|
|
184
|
-
const ctx = this.createContext();
|
|
185
|
-
let currentSystemPrompt = systemPrompt;
|
|
186
|
-
let systemPromptModified = false;
|
|
187
|
-
|
|
188
|
-
for (const ext of this.extensions) {
|
|
189
|
-
for (const handler of ext.handlers.get("before_agent_start") ?? []) {
|
|
190
|
-
try {
|
|
191
|
-
const event: BeforeAgentStartEvent = {
|
|
192
|
-
type: "before_agent_start",
|
|
193
|
-
prompt,
|
|
194
|
-
attachments,
|
|
195
|
-
systemPrompt: currentSystemPrompt,
|
|
196
|
-
systemPromptOptions,
|
|
197
|
-
};
|
|
198
|
-
const handlerResult = (await handler(event, ctx)) as BeforeAgentStartEventResult | undefined;
|
|
199
|
-
if (handlerResult?.systemPrompt !== undefined) {
|
|
200
|
-
currentSystemPrompt = handlerResult.systemPrompt;
|
|
201
|
-
systemPromptModified = true;
|
|
202
|
-
}
|
|
203
|
-
} catch (err) {
|
|
204
|
-
this.emitError(ext, "before_agent_start", err);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
return systemPromptModified ? currentSystemPrompt : undefined;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
/** Extensions are inline factories: they adjust the system prompt, the messages of a model call and tool results, and register tools. */
|
|
2
|
-
|
|
3
|
-
import type { AgentMessage, AgentToolResult, AgentToolUpdateCallback, ToolExecutionMode } from "../../loop/index.ts";
|
|
4
|
-
import type { ImageContent, Model, TextContent, UserAttachment } from "@ragents/ai";
|
|
5
|
-
import type { Static, TSchema } from "typebox";
|
|
6
|
-
import type { ReadonlySessionManager } from "../session-manager.ts";
|
|
7
|
-
import type { SourceInfo } from "../source-info.ts";
|
|
8
|
-
import type { BuildSystemPromptOptions } from "../system-prompt.ts";
|
|
9
|
-
|
|
10
|
-
export type { BuildSystemPromptOptions } from "../system-prompt.ts";
|
|
11
|
-
export type { AgentToolResult, AgentToolUpdateCallback, ToolExecutionMode };
|
|
12
|
-
|
|
13
|
-
/** Context passed to extension event handlers and tools. */
|
|
14
|
-
export interface ExtensionContext {
|
|
15
|
-
/** Session manager (read-only) */
|
|
16
|
-
sessionManager: ReadonlySessionManager;
|
|
17
|
-
/** Current model (may be undefined) */
|
|
18
|
-
model: Model<any> | undefined;
|
|
19
|
-
/** The current abort signal, or undefined when the agent is not streaming. */
|
|
20
|
-
signal: AbortSignal | undefined;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/** Tool definition for registerTool(). */
|
|
24
|
-
export interface ToolDefinition<TParams extends TSchema = TSchema, TDetails = unknown, TState = any> {
|
|
25
|
-
/** Tool name (used in LLM tool calls) */
|
|
26
|
-
name: string;
|
|
27
|
-
/** Human-readable label */
|
|
28
|
-
label: string;
|
|
29
|
-
/** Description for LLM */
|
|
30
|
-
description: string;
|
|
31
|
-
/** Optional one-line snippet for the Available tools section in the default system prompt. */
|
|
32
|
-
promptSnippet?: string;
|
|
33
|
-
/** Optional guideline bullets appended to the default system prompt Guidelines section when this tool is active. */
|
|
34
|
-
promptGuidelines?: string[];
|
|
35
|
-
/** Parameter schema (TypeBox) */
|
|
36
|
-
parameters: TParams;
|
|
37
|
-
/** Optional compatibility shim to prepare raw tool call arguments before schema validation. */
|
|
38
|
-
prepareArguments?: (args: unknown) => Static<TParams>;
|
|
39
|
-
/** Per-tool execution mode override; if omitted, the default execution mode applies. */
|
|
40
|
-
executionMode?: ToolExecutionMode;
|
|
41
|
-
/** Execute the tool. */
|
|
42
|
-
execute(
|
|
43
|
-
toolCallId: string,
|
|
44
|
-
params: Static<TParams>,
|
|
45
|
-
signal: AbortSignal | undefined,
|
|
46
|
-
onUpdate: AgentToolUpdateCallback<TDetails> | undefined,
|
|
47
|
-
ctx: ExtensionContext,
|
|
48
|
-
): Promise<AgentToolResult<TDetails>>;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
type AnyToolDefinition = ToolDefinition<any, any, any>;
|
|
52
|
-
|
|
53
|
-
/** Preserve parameter inference for standalone tool definitions. */
|
|
54
|
-
export function defineTool<TParams extends TSchema, TDetails = unknown, TState = any>(
|
|
55
|
-
tool: ToolDefinition<TParams, TDetails, TState>,
|
|
56
|
-
): ToolDefinition<TParams, TDetails, TState> & AnyToolDefinition {
|
|
57
|
-
return tool as ToolDefinition<TParams, TDetails, TState> & AnyToolDefinition;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/** Fired before each LLM call. Can modify messages. */
|
|
61
|
-
export interface ContextEvent {
|
|
62
|
-
type: "context";
|
|
63
|
-
messages: AgentMessage[];
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/** Fired after the user submits a prompt but before the agent loop. */
|
|
67
|
-
export interface BeforeAgentStartEvent {
|
|
68
|
-
type: "before_agent_start";
|
|
69
|
-
/** The raw user prompt text. */
|
|
70
|
-
prompt: string;
|
|
71
|
-
attachments?: UserAttachment[];
|
|
72
|
-
/** The fully assembled system prompt string. */
|
|
73
|
-
systemPrompt: string;
|
|
74
|
-
/** Structured options used to build the system prompt. */
|
|
75
|
-
systemPromptOptions: BuildSystemPromptOptions;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/** Fired after a tool executes. Can modify the result. */
|
|
79
|
-
export interface ToolResultEvent {
|
|
80
|
-
type: "tool_result";
|
|
81
|
-
toolCallId: string;
|
|
82
|
-
toolName: string;
|
|
83
|
-
input: Record<string, unknown>;
|
|
84
|
-
content: (TextContent | ImageContent)[];
|
|
85
|
-
details: unknown;
|
|
86
|
-
isError: boolean;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export type ExtensionEvent = ContextEvent | BeforeAgentStartEvent | ToolResultEvent;
|
|
90
|
-
|
|
91
|
-
export interface ContextEventResult {
|
|
92
|
-
messages?: AgentMessage[];
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export interface ToolResultEventResult {
|
|
96
|
-
content?: (TextContent | ImageContent)[];
|
|
97
|
-
details?: unknown;
|
|
98
|
-
isError?: boolean;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export interface BeforeAgentStartEventResult {
|
|
102
|
-
/** Replace the system prompt for this turn. If multiple extensions return this, they are chained. */
|
|
103
|
-
systemPrompt?: string;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/** Handler function type for events */
|
|
107
|
-
export type ExtensionHandler<E, R = undefined> = (event: E, ctx: ExtensionContext) => Promise<R | void> | R | void;
|
|
108
|
-
|
|
109
|
-
/** ExtensionAPI passed to extension factory functions. */
|
|
110
|
-
export interface ExtensionAPI {
|
|
111
|
-
on(event: "before_agent_start", handler: ExtensionHandler<BeforeAgentStartEvent, BeforeAgentStartEventResult>): void;
|
|
112
|
-
on(event: "context", handler: ExtensionHandler<ContextEvent, ContextEventResult>): void;
|
|
113
|
-
on(event: "tool_result", handler: ExtensionHandler<ToolResultEvent, ToolResultEventResult>): void;
|
|
114
|
-
|
|
115
|
-
/** Register a tool that the LLM can call. */
|
|
116
|
-
registerTool<TParams extends TSchema = TSchema, TDetails = unknown, TState = any>(
|
|
117
|
-
tool: ToolDefinition<TParams, TDetails, TState>,
|
|
118
|
-
): void;
|
|
119
|
-
|
|
120
|
-
/** Append a custom entry to the session for state persistence (not sent to LLM). */
|
|
121
|
-
appendEntry<T = unknown>(customType: string, data?: T): void;
|
|
122
|
-
|
|
123
|
-
/** Get all configured tools with parameter schema, prompt guidelines, and source metadata. */
|
|
124
|
-
getAllTools(): ToolInfo[];
|
|
125
|
-
|
|
126
|
-
/** Set the active tools by name. */
|
|
127
|
-
setActiveTools(toolNames: string[]): void;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
export interface ExtensionFactoryContext {
|
|
131
|
-
readonly signal: AbortSignal;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/** Extension factory function type. Supports both sync and async initialization. */
|
|
135
|
-
export type ExtensionFactory = (agent: ExtensionAPI, context: ExtensionFactoryContext) => void | Promise<void>;
|
|
136
|
-
|
|
137
|
-
/** Observes the actual lifetime of an async extension factory, independently of an aborted loader wait. */
|
|
138
|
-
export type ExtensionFactorySettlementObserver = (settlement: Promise<void>) => void;
|
|
139
|
-
|
|
140
|
-
export type InlineExtension =
|
|
141
|
-
| ExtensionFactory
|
|
142
|
-
| {
|
|
143
|
-
/** Display name shown as `<inline:name>`. */
|
|
144
|
-
name: string;
|
|
145
|
-
factory: ExtensionFactory;
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
export interface RegisteredTool {
|
|
149
|
-
definition: ToolDefinition;
|
|
150
|
-
sourceInfo: SourceInfo;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
type HandlerFn = (...args: unknown[]) => Promise<unknown>;
|
|
154
|
-
|
|
155
|
-
/** Tool info with name, description, parameter schema, prompt guidelines, and source metadata. */
|
|
156
|
-
export type ToolInfo = Pick<ToolDefinition, "name" | "description" | "parameters" | "promptGuidelines"> & {
|
|
157
|
-
sourceInfo: SourceInfo;
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
/** Action implementations behind the ExtensionAPI, provided by the session. */
|
|
161
|
-
export interface ExtensionActions {
|
|
162
|
-
appendEntry: <T = unknown>(customType: string, data?: T) => void;
|
|
163
|
-
getAllTools: () => ToolInfo[];
|
|
164
|
-
setActiveTools: (toolNames: string[]) => void;
|
|
165
|
-
refreshTools: () => void;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/** Shared state created by the loader; actions are throwing stubs until the runner binds the session. */
|
|
169
|
-
export interface ExtensionRuntime extends ExtensionActions {
|
|
170
|
-
/** Throws when this extension instance is stale. */
|
|
171
|
-
assertActive: () => void;
|
|
172
|
-
/** Marks this extension instance as stale. */
|
|
173
|
-
invalidate: (message?: string) => void;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/** Loaded extension with all registered items. */
|
|
177
|
-
export interface Extension {
|
|
178
|
-
path: string;
|
|
179
|
-
sourceInfo: SourceInfo;
|
|
180
|
-
handlers: Map<string, HandlerFn[]>;
|
|
181
|
-
tools: Map<string, RegisteredTool>;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/** Result of loading extensions. */
|
|
185
|
-
export interface LoadExtensionsResult {
|
|
186
|
-
extensions: Extension[];
|
|
187
|
-
errors: Array<{ path: string; error: string }>;
|
|
188
|
-
/** Shared runtime - actions are throwing stubs until the runner binds the session */
|
|
189
|
-
runtime: ExtensionRuntime;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
export interface ExtensionError {
|
|
193
|
-
extensionPath: string;
|
|
194
|
-
event: string;
|
|
195
|
-
error: string;
|
|
196
|
-
stack?: string;
|
|
197
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tool wrappers for extension-registered tools.
|
|
3
|
-
*
|
|
4
|
-
* These wrappers only adapt tool execution so extension tools receive the runner context.
|
|
5
|
-
* Tool result interception is handled by AgentSession via the hooks of the agent loop.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { AgentTool } from "../../loop/index.ts";
|
|
9
|
-
import type { ExtensionRunner } from "./runner.ts";
|
|
10
|
-
import type { RegisteredTool } from "./types.ts";
|
|
11
|
-
|
|
12
|
-
/** Wrap registered tools into AgentTools that receive the runner context on every call. */
|
|
13
|
-
export function wrapRegisteredTools(registeredTools: RegisteredTool[], runner: ExtensionRunner): AgentTool[] {
|
|
14
|
-
return registeredTools.map(({ definition }) => ({
|
|
15
|
-
name: definition.name,
|
|
16
|
-
label: definition.label,
|
|
17
|
-
description: definition.description,
|
|
18
|
-
parameters: definition.parameters,
|
|
19
|
-
prepareArguments: definition.prepareArguments,
|
|
20
|
-
executionMode: definition.executionMode,
|
|
21
|
-
execute: (toolCallId, params, signal, onUpdate) =>
|
|
22
|
-
definition.execute(toolCallId, params, signal, onUpdate, runner.createContext()),
|
|
23
|
-
}));
|
|
24
|
-
}
|