@alneas/eaos-server 0.1.0 → 0.2.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/CHANGELOG.md +20 -0
- package/README.ja.md +28 -18
- package/README.md +8 -2
- package/dist/agentic/agent-jobs.d.ts +5 -1
- package/dist/agentic/autonomous-worker.d.ts +30 -3
- package/dist/agentic/autonomous-worker.js +2 -1
- package/dist/agentic/event-bridge.d.ts +6 -0
- package/dist/agentic/index.d.ts +7 -3
- package/dist/agentic/index.js +2 -1
- package/dist/agentic/local-runner.d.ts +6 -2
- package/dist/chunk-4BARRLJR.js +180 -0
- package/dist/chunk-4BARRLJR.js.map +1 -0
- package/dist/{chunk-THYUY5ZZ.js → chunk-F2J6IQ6I.js} +68 -25
- package/dist/chunk-F2J6IQ6I.js.map +1 -0
- package/dist/{chunk-6KV5CJBW.js → chunk-F4IITPGX.js} +5 -5
- package/dist/{chunk-DHQGNP4T.js → chunk-SDJNYPYK.js} +2 -2
- package/dist/{chunk-DHQGNP4T.js.map → chunk-SDJNYPYK.js.map} +1 -1
- package/dist/chunk-YMHVRBUU.js +199 -0
- package/dist/chunk-YMHVRBUU.js.map +1 -0
- package/dist/db-package/index.js +3 -3
- package/dist/engine.js +2 -2
- package/dist/execution/chat.d.ts +7 -0
- package/dist/execution/chat.js +7 -0
- package/dist/execution/chat.js.map +1 -0
- package/dist/execution/index.d.ts +294 -2
- package/dist/execution/index.js +10 -1
- package/dist/execution/index.js.map +1 -1
- package/dist/execution/tool-agent.d.ts +7 -0
- package/dist/execution/tool-agent.js +8 -0
- package/dist/execution/tool-agent.js.map +1 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +4 -3
- package/dist/lifecycle-engine/backend-migration.js +1 -1
- package/dist/lifecycle-engine/baseline.js +1 -1
- package/dist/lifecycle-engine/index.js +1 -1
- package/dist/lifecycle-engine/platform/index.js +8 -8
- package/dist/sql-lifecycle/index.d.ts +1 -1
- package/docs/api.md +809 -2
- package/docs/guide.md +44 -0
- package/docs/index.md +6 -2
- package/package.json +12 -3
- package/dist/chunk-THYUY5ZZ.js.map +0 -1
- /package/dist/{chunk-6KV5CJBW.js.map → chunk-F4IITPGX.js.map} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @alneas/eaos-server
|
|
2
2
|
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Expose canonical `createChatClient` and `createToolAgent` execution APIs backed by existing Appkit chat, Action and execution-session primitives. Connect live authorization, model routes, limits, cancellation, guards, budgets, usage and observations.
|
|
8
|
+
- Route built-in LiteLLM tasks through the same chat client. Support Host-owned authentication headers and optional shared chat configuration without changing injected-executor priority or Goose/Hermes process execution.
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Align English/Japanese setup and support guidance with actual package requirements; link the existing GitHub private reporting channel without adding a support guarantee.
|
|
13
|
+
|
|
14
|
+
- Consume EAOS Core ^0.2.0 and reauthorize after asynchronous guards/accounting/telemetry, before returning output. Recheck retained tool history before each subsequent model request.
|
|
15
|
+
- Require explicit model-to-adapter bindings when a model registry is configured. Reject protocol-reserved provider parameters rather than allowing them to override the selected model or messages.
|
|
16
|
+
|
|
17
|
+
### Upgrade
|
|
18
|
+
|
|
19
|
+
- Built-in LiteLLM now requests OpenAI-compatible SSE streams. JSON-only custom endpoints must provide a compatible Host adapter or injected executor. Existing task result envelopes, endpoint/model/fetch options, HTTP status errors, output ceilings and process dispatch remain supported; common stream, cancellation and validation failures use shared chat diagnostics.
|
|
20
|
+
- Provider usage may be unavailable in Appkit events. Host accounting receives unknown usage explicitly and must reconcile it instead of treating it as zero; accounting failures propagate. Keep external side-effect idempotency and durable accounting in the Host.
|
|
21
|
+
- Install Core 0.2.0 before Server 0.2.0. This update performs no migrations or tenant activation.
|
|
22
|
+
|
|
3
23
|
## 0.1.0
|
|
4
24
|
|
|
5
25
|
### Added
|
package/README.ja.md
CHANGED
|
@@ -1,27 +1,36 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Server の実行と永続化
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[English](https://github.com/dataarthub/eaos/blob/main/packages/server/README.md) | [日本語](https://github.com/dataarthub/eaos/blob/main/packages/server/README.ja.md)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[ドキュメントサイトの日本語ページ](https://tech-docs.alneas.com/ja/eaos-workspace/server/)でプロジェクト全体の日本語ドキュメントを案内しています。未翻訳・レビュー待ちのページは英語にフォールバックする場合があります。公開サイトは公開済みバージョンの案内であり、この README の 0.2.0 候補と一致しない場合は、対応する英語ガイドと変更履歴を確認してください。
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
[](https://www.typescriptlang.org/docs/) [](https://nodejs.org/en/about/previous-releases) [](https://hono.dev/docs/)
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## Elevator Pitch
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
ホスト開発者は Server を使い、HTTP/MCP、ライフサイクル、永続データサービスを構成できます。
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
- 明示的なホスト接続と現在の認可
|
|
15
|
-
- パッケージ単位の検証と配布
|
|
13
|
+
## Why & Value
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
共通実装により、認可、CAS、監査、Outbox の振る舞いを揃えます。プロバイダーへの接続、現在の識別情報、デプロイ方針はホストが管理します。この MIT パッケージの実装と型宣言は公開モノレポで管理します。
|
|
18
16
|
|
|
19
|
-
|
|
17
|
+
## Key Highlights
|
|
20
18
|
|
|
21
|
-
|
|
19
|
+
- Hono と MCP の連携
|
|
20
|
+
- レビューを経たライフサイクル計画
|
|
21
|
+
- 永続的な CAS と監査
|
|
22
|
+
- スコープを限定したデータベースとストレージ
|
|
23
|
+
|
|
24
|
+
## Quickstart
|
|
25
|
+
|
|
26
|
+
この checkout は 0.2.0 のリリース準備用です。0.1.0 は公開済みです。0.2.0 の公開まではチェックサムを固定した候補 tarball を導入し、以下のコマンドは公開後に使用してください。
|
|
27
|
+
|
|
28
|
+
### 公開 API の import
|
|
29
|
+
|
|
30
|
+
Node.js 24 以上と、必須 peer の Appkit Core 0.2.0 を使用してください。以下の正規化の例は純粋な処理で、データベース接続や認証情報は不要です。Server の実行には、別途ホストが管理する識別情報、認可、永続化の接続が必要です。subpath は import の対象であり、個別にインストールするパッケージではありません。
|
|
22
31
|
|
|
23
32
|
```bash
|
|
24
|
-
bun add @alneas/eaos-server @alneas/appkit-core@0.2.0
|
|
33
|
+
bun add @alneas/eaos-server@0.2.0 @alneas/appkit-core@0.2.0
|
|
25
34
|
```
|
|
26
35
|
|
|
27
36
|
```typescript
|
|
@@ -30,10 +39,11 @@ import { canonical } from '@alneas/eaos-server/lifecycle-engine'
|
|
|
30
39
|
console.log(canonical({ format: 1, operation: 'inspect' }))
|
|
31
40
|
```
|
|
32
41
|
|
|
33
|
-
##
|
|
34
|
-
|
|
35
|
-
- [Architecture and boundaries](docs/guide.md)
|
|
36
|
-
- [API reference](docs/api.md)
|
|
37
|
-
- [EAOS composition](https://tech-docs.alneas.com/eaos-workspace/architecture/)
|
|
42
|
+
## Next Steps
|
|
38
43
|
|
|
39
44
|
- [変更履歴](https://github.com/dataarthub/eaos/blob/main/packages/server/CHANGELOG.md)
|
|
45
|
+
- [アーキテクチャと境界](docs/guide.md)
|
|
46
|
+
- [API リファレンス](docs/api.md)
|
|
47
|
+
- [EAOS の構成](https://tech-docs.alneas.com/eaos-workspace/architecture/)
|
|
48
|
+
|
|
49
|
+
英語での質問・不具合報告を [GitHub Issues](https://github.com/dataarthub/eaos/issues) で受け付けています。非公開の脆弱性報告には [GitHubの非公開報告機能](https://github.com/dataarthub/eaos/security/advisories/new)を利用できます。
|
package/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Server execution and persistence
|
|
2
2
|
|
|
3
|
+
[English](https://github.com/dataarthub/eaos/blob/main/packages/server/README.md) | [日本語](https://github.com/dataarthub/eaos/blob/main/packages/server/README.ja.md)
|
|
4
|
+
|
|
5
|
+
[](https://www.typescriptlang.org/docs/) [](https://nodejs.org/en/about/previous-releases) [](https://hono.dev/docs/)
|
|
6
|
+
|
|
3
7
|
## Elevator Pitch
|
|
4
8
|
|
|
5
9
|
Host developers use Server to compose HTTP/MCP, lifecycle and durable data services.
|
|
@@ -17,14 +21,14 @@ Shared implementations keep authorization, CAS, audit and Outbox consistent. The
|
|
|
17
21
|
|
|
18
22
|
## Quickstart
|
|
19
23
|
|
|
20
|
-
|
|
24
|
+
This checkout prepares version 0.2.0; version 0.1.0 is already published. Until 0.2.0 is published, install the checksum-pinned candidate tarball. The command below applies after that release.
|
|
21
25
|
|
|
22
26
|
### Public import
|
|
23
27
|
|
|
24
28
|
Use Node.js 24 or later and the required Appkit Core 0.2.0 peer. The canonicalization example is pure and needs no database connection or credentials. Server execution later requires host-owned identity, authorization and persistence bindings. The subpath is an import target, not a separately installed package.
|
|
25
29
|
|
|
26
30
|
```bash
|
|
27
|
-
bun add @alneas/eaos-server @alneas/appkit-core@0.2.0
|
|
31
|
+
bun add @alneas/eaos-server@0.2.0 @alneas/appkit-core@0.2.0
|
|
28
32
|
```
|
|
29
33
|
|
|
30
34
|
```typescript
|
|
@@ -39,3 +43,5 @@ console.log(canonical({ format: 1, operation: 'inspect' }))
|
|
|
39
43
|
- [Architecture and boundaries](docs/guide.md)
|
|
40
44
|
- [API reference](docs/api.md)
|
|
41
45
|
- [EAOS composition](https://tech-docs.alneas.com/eaos-workspace/architecture/)
|
|
46
|
+
|
|
47
|
+
Questions and issue reports in English are welcome in [GitHub Issues](https://github.com/dataarthub/eaos/issues). Private vulnerability reports can use [GitHub private reporting](https://github.com/dataarthub/eaos/security/advisories/new).
|
|
@@ -2,9 +2,13 @@ import { AgentJobRecord } from '@alneas/eaos-core';
|
|
|
2
2
|
import { ServerAgentDispatchMode, ServerAgentTaskRequest, ServerAgentTaskResult } from './types.js';
|
|
3
3
|
import { ServerAutonomousWorker } from './autonomous-worker.js';
|
|
4
4
|
import { AtomicRepository, PluginPrincipal, AtomicSession } from '../plugin-data/index.js';
|
|
5
|
+
import '@alneas/appkit-core/ai/ai-chat';
|
|
6
|
+
import '../execution/index.js';
|
|
7
|
+
import '@alneas/appkit-core/ai/action';
|
|
5
8
|
import 'hono/types';
|
|
6
|
-
import '@alneas/eaos-core/plugin-sdk';
|
|
7
9
|
import 'hono';
|
|
10
|
+
import '@alneas/appkit-core/ai';
|
|
11
|
+
import '@alneas/eaos-core/plugin-sdk';
|
|
8
12
|
import '@alneas/eaos-server/lifecycle-engine';
|
|
9
13
|
|
|
10
14
|
/**
|
|
@@ -1,6 +1,23 @@
|
|
|
1
|
+
import { AIChatAdapter } from '@alneas/appkit-core/ai/ai-chat';
|
|
2
|
+
import { ChatClientOptions } from '../execution/index.js';
|
|
1
3
|
import { McpGatekeeper, AgentRuntimeResourcePolicy } from '@alneas/eaos-core';
|
|
2
4
|
import { ServerAgentWorkerType, ServerAgentExecutor, ServerAgentTaskRequest, ServerAgentTaskResult } from './types.js';
|
|
5
|
+
import '@alneas/appkit-core/ai/action';
|
|
6
|
+
import 'hono/types';
|
|
7
|
+
import 'hono';
|
|
8
|
+
import '@alneas/appkit-core/ai';
|
|
3
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Host composition of the shared chat path for built-in model tasks.
|
|
12
|
+
* @remarks Defaults retain the worker gatekeeper, 60-second task timeout and worker output bound. Tools are undisclosed; action orchestration belongs to createToolAgent. No model transport or credential is selected from model output.
|
|
13
|
+
* @see ServerWorkerOptions for complete worker configuration.
|
|
14
|
+
*/
|
|
15
|
+
interface ServerWorkerChatOptions extends Omit<ChatClientOptions, 'adapter' | 'authorize' | 'tools'> {
|
|
16
|
+
/** Optional host adapter; omission uses Appkit's OpenAI-compatible LiteLLM transport. */
|
|
17
|
+
adapter?: AIChatAdapter;
|
|
18
|
+
/** Optional live Host authorization, combined with the worker gatekeeper before and after asynchronous work. */
|
|
19
|
+
authorize?: ChatClientOptions['authorize'];
|
|
20
|
+
}
|
|
4
21
|
/**
|
|
5
22
|
* Trusted gatekeeper, runtime endpoints/adapters, and execution limits for {@link ServerAutonomousWorker}.
|
|
6
23
|
*/
|
|
@@ -15,6 +32,10 @@ interface ServerWorkerOptions {
|
|
|
15
32
|
litellmEndpoint?: string;
|
|
16
33
|
/** Host model identifier; defaults to LITELLM_MODEL and is required for built-in LiteLLM execution. */
|
|
17
34
|
litellmModel?: string;
|
|
35
|
+
/** Host-owned provider headers; captured at construction and never read from task/model input. */
|
|
36
|
+
litellmHeaders?: Readonly<Record<string, string>>;
|
|
37
|
+
/** Optional shared chat model routing, live authorization, limits, guards, usage, budget and observability. */
|
|
38
|
+
chat?: ServerWorkerChatOptions;
|
|
18
39
|
/** Combined command output/string result ceiling, safe integer 1–10000000; defaults to 1000000. */
|
|
19
40
|
maxOutputChars?: number;
|
|
20
41
|
/** Framework default is safe for the ARM agent host. Host adapters may tighten it. */
|
|
@@ -46,6 +67,8 @@ declare class ServerAutonomousWorker {
|
|
|
46
67
|
private hermesAgentPath;
|
|
47
68
|
private litellmUrl;
|
|
48
69
|
private litellmModel?;
|
|
70
|
+
private litellmHeaders;
|
|
71
|
+
private chatOptions;
|
|
49
72
|
private maxOutputChars;
|
|
50
73
|
private runtimePolicy;
|
|
51
74
|
private runtimeRole;
|
|
@@ -61,9 +84,10 @@ declare class ServerAutonomousWorker {
|
|
|
61
84
|
/**
|
|
62
85
|
* Checks task limits and gatekeeper policy before dispatching one runtime attempt.
|
|
63
86
|
* @param request - Verified task identity and instructions; required strings must be nonblank, title at most 500 characters, instructions at most 1000000, and timeout a safe integer 1–3600000 milliseconds when provided.
|
|
87
|
+
* @param execution - Optional cancellation signal for built-in shared chat tasks; does not change injected executor or process contracts.
|
|
64
88
|
* @returns COMPLETED text output, PENDING_APPROVAL ticket data without execution, or FAILED data with error and optional classification/retry advice. Duration is measured in wall-clock milliseconds.
|
|
65
89
|
* @throws Can reject a throwing gatekeeper or malformed gatekeeper interaction before dispatch; runtime execution errors are normally returned as FAILED data.
|
|
66
|
-
* @remarks Gatekeeper receives fixed agent/server_bot roles rather than request user roles. Approval tickets are generated but not persisted here. The configured framework policy overrides request.runtimePolicy before execution. Injected executors and built-in
|
|
90
|
+
* @remarks Gatekeeper receives fixed agent/server_bot roles rather than request user roles. Approval tickets are generated but not persisted here. The configured framework policy overrides request.runtimePolicy before execution. Injected executors and built-in chat outputs are bounded by maxOutputChars. LiteLLM uses Appkit SSE transport through createChatClient; JSON-only endpoints require a Host adapter or executor. Existing FAILED/PENDING_APPROVAL/COMPLETED envelopes and injected-executor priority remain unchanged.
|
|
67
91
|
* @example
|
|
68
92
|
* ```typescript
|
|
69
93
|
* import { ServerAutonomousWorker, type ServerWorkerOptions } from "@alneas/eaos-server/agentic/autonomous-worker";
|
|
@@ -73,7 +97,10 @@ declare class ServerAutonomousWorker {
|
|
|
73
97
|
* }
|
|
74
98
|
* ```
|
|
75
99
|
*/
|
|
76
|
-
runTask(request: ServerAgentTaskRequest
|
|
100
|
+
runTask(request: ServerAgentTaskRequest, execution?: {
|
|
101
|
+
/** Cooperatively cancel built-in shared chat. Injected executors and Goose/Hermes retain their own cancellation contracts. */
|
|
102
|
+
signal?: AbortSignal;
|
|
103
|
+
}): Promise<ServerAgentTaskResult>;
|
|
77
104
|
private execute;
|
|
78
105
|
/**
|
|
79
106
|
* Execute Goose in headless batch mode
|
|
@@ -92,4 +119,4 @@ declare class ServerAutonomousWorker {
|
|
|
92
119
|
}
|
|
93
120
|
|
|
94
121
|
export { ServerAutonomousWorker };
|
|
95
|
-
export type { ServerRuntimeRole, ServerWorkerOptions };
|
|
122
|
+
export type { ServerRuntimeRole, ServerWorkerChatOptions, ServerWorkerOptions };
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { DomainEventBus } from '@alneas/eaos-core';
|
|
2
2
|
import { ServerAutonomousWorker } from './autonomous-worker.js';
|
|
3
3
|
import { ServerAgentTaskRequest, ServerAgentTaskResult } from './types.js';
|
|
4
|
+
import '@alneas/appkit-core/ai/ai-chat';
|
|
5
|
+
import '../execution/index.js';
|
|
6
|
+
import '@alneas/appkit-core/ai/action';
|
|
7
|
+
import 'hono/types';
|
|
8
|
+
import 'hono';
|
|
9
|
+
import '@alneas/appkit-core/ai';
|
|
4
10
|
|
|
5
11
|
/**
|
|
6
12
|
* Maps one domain event name to a verified host task specification.
|
package/dist/agentic/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { ServerAgentDispatchMode, ServerAgentExecutionContext, ServerAgentExecutionError, ServerAgentExecutor, ServerAgentTaskRequest, ServerAgentTaskResult, ServerAgentWorkerType, ServerApprovalCallbackPayload } from './types.js';
|
|
2
|
-
export { ServerAutonomousWorker, ServerRuntimeRole, ServerWorkerOptions } from './autonomous-worker.js';
|
|
2
|
+
export { ServerAutonomousWorker, ServerRuntimeRole, ServerWorkerChatOptions, ServerWorkerOptions } from './autonomous-worker.js';
|
|
3
3
|
export { CommandAgentExecutorOptions, CommandAgentSandboxMode, CommandAgentSandboxOptions, buildSystemdRunArgs, createCommandAgentExecutor, validateAgentRuntimePolicy } from './executor.js';
|
|
4
4
|
export { ServerWorkflowAgentRunnerOptions, createWorkflowAgentRunner } from './agent-runner.js';
|
|
5
5
|
export { WorkflowAgentNodeOptions, createWorkflowAgentNode } from './agent-node.js';
|
|
@@ -16,9 +16,13 @@ export { WorkflowNodeCatalog, WorkflowNodeDescriptor, WorkflowNodeRegistration,
|
|
|
16
16
|
export { CompiledWorkflow, WorkflowCompilerOptions, compileWorkflowDefinition } from './workflow-compiler.js';
|
|
17
17
|
export { InMemoryWorkflowDefinitionRegistry, WorkflowDefinitionRecord, WorkflowDefinitionRegistry } from './workflow-registry.js';
|
|
18
18
|
import '@alneas/eaos-core';
|
|
19
|
+
import '@alneas/appkit-core/ai/ai-chat';
|
|
20
|
+
import '../execution/index.js';
|
|
21
|
+
import '@alneas/appkit-core/ai/action';
|
|
22
|
+
import 'hono/types';
|
|
23
|
+
import 'hono';
|
|
24
|
+
import '@alneas/appkit-core/ai';
|
|
19
25
|
import '@langchain/langgraph';
|
|
20
26
|
import '../plugin-data/index.js';
|
|
21
|
-
import 'hono/types';
|
|
22
27
|
import '@alneas/eaos-core/plugin-sdk';
|
|
23
|
-
import 'hono';
|
|
24
28
|
import '@alneas/eaos-server/lifecycle-engine';
|
package/dist/agentic/index.js
CHANGED
|
@@ -2,10 +2,14 @@ import { AgentJobKind, AgentJobRecord } from '@alneas/eaos-core';
|
|
|
2
2
|
import { AgentJobStore } from './agent-jobs.js';
|
|
3
3
|
import { ServerAgentTaskRequest, ServerAgentTaskResult } from './types.js';
|
|
4
4
|
import './autonomous-worker.js';
|
|
5
|
-
import '
|
|
5
|
+
import '@alneas/appkit-core/ai/ai-chat';
|
|
6
|
+
import '../execution/index.js';
|
|
7
|
+
import '@alneas/appkit-core/ai/action';
|
|
6
8
|
import 'hono/types';
|
|
7
|
-
import '@alneas/eaos-core/plugin-sdk';
|
|
8
9
|
import 'hono';
|
|
10
|
+
import '@alneas/appkit-core/ai';
|
|
11
|
+
import '../plugin-data/index.js';
|
|
12
|
+
import '@alneas/eaos-core/plugin-sdk';
|
|
9
13
|
import '@alneas/eaos-server/lifecycle-engine';
|
|
10
14
|
|
|
11
15
|
/**
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createChatClient
|
|
3
|
+
} from "./chunk-YMHVRBUU.js";
|
|
4
|
+
|
|
5
|
+
// src/execution/tool-agent.ts
|
|
6
|
+
import { createActionToolBridge, createExecutionSession } from "@alneas/appkit-core/ai/action";
|
|
7
|
+
function createToolAgent(options) {
|
|
8
|
+
const { session: makeSession, disclose, authorizeCall, authorize } = options;
|
|
9
|
+
const maxRounds = options.maxRounds ?? 6, maxCalls = options.maxCalls ?? 10, maxChars = options.maxInputChars ?? 2e5;
|
|
10
|
+
if (typeof makeSession !== "function" || typeof disclose !== "function" || typeof authorizeCall !== "function" || typeof authorize !== "function" || !Number.isSafeInteger(maxRounds) || maxRounds < 1 || maxRounds > 20 || !Number.isSafeInteger(maxCalls) || maxCalls < 1 || maxCalls > 100) throw new Error("Agent policy and valid limits required");
|
|
11
|
+
const chatOptions = { ...options, parameters: structuredClone(options.parameters), modelAdapters: options.modelAdapters && Object.freeze({ ...options.modelAdapters }) };
|
|
12
|
+
const execution = createExecutionSession();
|
|
13
|
+
return {
|
|
14
|
+
/**
|
|
15
|
+
* Request cooperative cancellation of the current Appkit execution.
|
|
16
|
+
* @returns No value; Appkit marks active work cancelling without rolling back completed effects.
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* import { createToolAgent } from '@alneas/eaos-server/execution/tool-agent';
|
|
20
|
+
* export function cancel(agent: ReturnType<typeof createToolAgent>) { return agent.cancel(); }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
cancel: () => execution.cancel(),
|
|
24
|
+
/**
|
|
25
|
+
* Read Appkit's summary-only in-memory execution history.
|
|
26
|
+
* @returns Appkit execution summaries; raw model inputs/results are not stored in these summaries.
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* import { createToolAgent } from '@alneas/eaos-server/execution/tool-agent';
|
|
30
|
+
* export function snapshot(agent: ReturnType<typeof createToolAgent>) { return agent.getSnapshot(); }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
getSnapshot: () => execution.getSnapshot(),
|
|
34
|
+
/**
|
|
35
|
+
* Subscribe to Appkit execution summary changes.
|
|
36
|
+
* @param listener - Callback notified when execution state changes; do not expose raw secrets in UI callbacks.
|
|
37
|
+
* @returns Unsubscribe function owned by the subscribing host.
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* import { createToolAgent } from '@alneas/eaos-server/execution/tool-agent';
|
|
41
|
+
* export function observe(agent: ReturnType<typeof createToolAgent>, listener: () => void) { return agent.subscribe(listener); }
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
subscribe: (listener) => execution.subscribe(listener),
|
|
45
|
+
/**
|
|
46
|
+
* Close the Appkit session and request cooperative cancellation.
|
|
47
|
+
* @returns No value; the session no longer admits new runs.
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* import { createToolAgent } from '@alneas/eaos-server/execution/tool-agent';
|
|
51
|
+
* export function close(agent: ReturnType<typeof createToolAgent>) { agent.close(); }
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
close: () => execution.close(),
|
|
55
|
+
/**
|
|
56
|
+
* Run a single authorized model/Action conversation.
|
|
57
|
+
* @param principal - Verified current tenant/user identity, copied before host callbacks.
|
|
58
|
+
* @param input - Detached initial messages and optional cooperative cancellation signal.
|
|
59
|
+
* @returns Appkit execution outcome containing a ToolAgentResult on success; failed/cancelled outcomes omit it.
|
|
60
|
+
* @throws Appkit rejects concurrent or closed session admission; run failures otherwise become outcomes.
|
|
61
|
+
* @example
|
|
62
|
+
* ```typescript
|
|
63
|
+
* import { createToolAgent } from '@alneas/eaos-server/execution/tool-agent';
|
|
64
|
+
* export function run(agent: ReturnType<typeof createToolAgent>, ...args: Parameters<typeof agent.run>) { return agent.run(...args); }
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
async run(principal, input) {
|
|
68
|
+
const p = structuredClone(principal), messages = structuredClone(input.messages);
|
|
69
|
+
return execution.run("AI tool session", async (context) => {
|
|
70
|
+
const externalAbort = () => execution.cancel();
|
|
71
|
+
input.signal?.addEventListener("abort", externalAbort, { once: true });
|
|
72
|
+
if (input.signal?.aborted) externalAbort();
|
|
73
|
+
let bridge;
|
|
74
|
+
let callsExecuted = 0;
|
|
75
|
+
const check = async () => {
|
|
76
|
+
if (context.signal.aborted) throw new DOMException("Agent cancelled", "AbortError");
|
|
77
|
+
if (!p || [p.tenantId, p.userId].some((v) => typeof v !== "string" || !v.trim()) || await authorize(structuredClone(p), "model:chat") !== true) throw new Error("Agent access denied");
|
|
78
|
+
if (context.signal.aborted) throw new DOMException("Agent cancelled", "AbortError");
|
|
79
|
+
if (!Array.isArray(messages) || !messages.length || messages.length > 1e3 || JSON.stringify(messages).length > maxChars) throw new Error("Agent history limit");
|
|
80
|
+
};
|
|
81
|
+
const allowed = async (call) => {
|
|
82
|
+
await check();
|
|
83
|
+
if (await disclose(structuredClone(p), call.name) !== true || await authorizeCall(structuredClone(p), structuredClone(call)) !== true) throw new Error("Agent tool access denied");
|
|
84
|
+
await check();
|
|
85
|
+
};
|
|
86
|
+
const result = (status, pending = []) => ({ status, messages: structuredClone(messages), pending: structuredClone(pending), callsExecuted });
|
|
87
|
+
try {
|
|
88
|
+
await check();
|
|
89
|
+
const session = await makeSession(structuredClone(p));
|
|
90
|
+
await check();
|
|
91
|
+
if (!Array.isArray(session.tools) || session.tools.length > 100 || session.tools.some((tool) => !["read", "handoff"].includes(tool.mode))) throw new Error("Invalid agent tool policy");
|
|
92
|
+
const modes = new Map(session.tools.map((tool) => [tool.binding.name, tool.mode]));
|
|
93
|
+
const registrations = new Map(session.tools.filter((tool) => tool.binding.kind === "action").map((tool) => {
|
|
94
|
+
const binding = tool.binding;
|
|
95
|
+
return [binding.name, { id: binding.actionId, action: session.registry.getAction(binding.actionId) }];
|
|
96
|
+
}));
|
|
97
|
+
bridge = createActionToolBridge(session.registry, { tools: session.tools.map((tool) => tool.binding), maxCalls });
|
|
98
|
+
const activeBridge = bridge;
|
|
99
|
+
const authorizeHistory = async (history) => {
|
|
100
|
+
const prior = /* @__PURE__ */ new Map(), results = /* @__PURE__ */ new Set();
|
|
101
|
+
for (const message of history) for (const part of message.parts) {
|
|
102
|
+
if (part.type === "tool-call") {
|
|
103
|
+
if (prior.has(part.callId) || !modes.has(part.name)) throw new Error("Agent retained tool history is invalid");
|
|
104
|
+
const call = { callId: part.callId, name: part.name, arguments: part.input };
|
|
105
|
+
prior.set(call.callId, call);
|
|
106
|
+
await allowed(call);
|
|
107
|
+
} else if (part.type === "tool-result") {
|
|
108
|
+
const call = prior.get(part.callId);
|
|
109
|
+
if (!call || call.name !== part.name || results.has(part.callId)) throw new Error("Agent retained tool result has no unique authorized call");
|
|
110
|
+
results.add(part.callId);
|
|
111
|
+
await allowed(call);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
const authorizeAdapter = (transport) => ({
|
|
116
|
+
id: transport.id,
|
|
117
|
+
capabilities: transport.capabilities,
|
|
118
|
+
async *stream(request) {
|
|
119
|
+
for (const descriptor of request.tools ?? []) {
|
|
120
|
+
if (!modes.has(descriptor.name) || await disclose(structuredClone(p), descriptor.name) !== true) throw new Error("Agent tool descriptor disclosure denied");
|
|
121
|
+
}
|
|
122
|
+
await check();
|
|
123
|
+
await authorizeHistory(request.messages);
|
|
124
|
+
request.signal?.throwIfAborted();
|
|
125
|
+
yield* transport.stream(request);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
const chat = createChatClient({
|
|
129
|
+
...chatOptions,
|
|
130
|
+
authorize: async (actor, operation) => {
|
|
131
|
+
if (await authorize(actor, operation) !== true) return false;
|
|
132
|
+
await authorizeHistory(messages);
|
|
133
|
+
return true;
|
|
134
|
+
},
|
|
135
|
+
adapter: authorizeAdapter(chatOptions.adapter),
|
|
136
|
+
...chatOptions.modelAdapters ? { modelAdapters: Object.fromEntries(Object.entries(chatOptions.modelAdapters).map(([model, adapter]) => [model, authorizeAdapter(adapter)])) } : {},
|
|
137
|
+
tools: async () => {
|
|
138
|
+
const tools = [];
|
|
139
|
+
for (const tool of activeBridge.listTools()) if (await disclose(structuredClone(p), tool.name) === true) tools.push(tool);
|
|
140
|
+
return tools;
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
for (let round = 0; round < maxRounds; round++) {
|
|
144
|
+
await check();
|
|
145
|
+
const answer = await chat.complete(p, { messages, signal: context.signal, tools: "catalog" });
|
|
146
|
+
messages.push(answer.message);
|
|
147
|
+
await check();
|
|
148
|
+
if (answer.finishReason === "stop") return result("completed");
|
|
149
|
+
const calls = answer.message.parts.filter((part) => part.type === "tool-call").map((part) => ({ callId: part.callId, name: part.name, arguments: part.input }));
|
|
150
|
+
for (const call of calls) await allowed(call);
|
|
151
|
+
if (calls.some((call) => modes.get(call.name) === "handoff")) return result("handoff", calls);
|
|
152
|
+
if (callsExecuted + calls.length > maxCalls || round + 1 === maxRounds) return result("limited", calls);
|
|
153
|
+
for (let index = 0; index < calls.length; index++) {
|
|
154
|
+
const call = calls[index];
|
|
155
|
+
await allowed(call);
|
|
156
|
+
const registration = registrations.get(call.name);
|
|
157
|
+
if (registration && session.registry.getAction(registration.id) !== registration.action) throw new Error("Agent action registration changed");
|
|
158
|
+
const output = await activeBridge.execute(call, context);
|
|
159
|
+
callsExecuted++;
|
|
160
|
+
await allowed(call);
|
|
161
|
+
messages.push({ id: crypto.randomUUID(), role: "tool", parts: [{ type: "tool-result", callId: call.callId, name: call.name, output: output.ok ? output.data : { code: output.code, error: output.error }, ...!output.ok ? { isError: true } : {} }] });
|
|
162
|
+
await check();
|
|
163
|
+
context.reportProgress({ completed: callsExecuted, total: maxCalls });
|
|
164
|
+
if (!output.ok) return result("tool-error", calls.slice(index + 1));
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return result("limited");
|
|
168
|
+
} finally {
|
|
169
|
+
bridge?.close();
|
|
170
|
+
input.signal?.removeEventListener("abort", externalAbort);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export {
|
|
178
|
+
createToolAgent
|
|
179
|
+
};
|
|
180
|
+
//# sourceMappingURL=chunk-4BARRLJR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/execution/tool-agent.ts"],"sourcesContent":["import { createActionToolBridge, createExecutionSession, type ActionRegistry, type ActionToolDescriptor, type ActionToolBinding, type ActionToolCall } from '@alneas/appkit-core/ai/action'\nimport type { AIChatAdapter, AIChatMessage, AIChatPart } from '@alneas/appkit-core/ai/ai-chat'\nimport { createChatClient, type ChatClientOptions } from './chat'\nimport type { ExecutionPrincipal } from './index'\n\n/** Host-registered Action binding and explicit automatic-execution policy.\n * @see createToolAgent\n */\nexport interface AgentTool {\n /** Existing Appkit Action/command binding; registration and input/output schemas remain Appkit-owned. */\n binding: ActionToolBinding\n /** Only host-verified read-only actions may run automatically; handoffs remain unexecuted. */\n mode: 'read' | 'handoff'\n}\n/** Current host policies and limits for a single-flight Appkit execution session.\n * @see createToolAgent\n */\nexport interface ToolAgentOptions extends Omit<ChatClientOptions, 'tools'> {\n /**\n * Resolve the current host registry and explicit tool execution policy.\n * @param principal - Copied verified tenant/user identity.\n * @returns Existing Action registry and at most 100 read/handoff bindings.\n * @throws Rejects missing host session or registry resolution failures.\n * @example\n * ```typescript\n * import type { ToolAgentOptions } from '@alneas/eaos-server/execution/tool-agent';\n * export function agentSession(resolve: ToolAgentOptions['session']) { return resolve; }\n * ```\n */\n session(principal: ExecutionPrincipal): Promise<{\n /** Existing host-owned Appkit Action registry for this authorized session. */\n registry: ActionRegistry\n /** Explicit read/handoff policy for every disclosed binding. */\n tools: readonly AgentTool[]\n }>\n /**\n * Check current permission to disclose a tool descriptor or result to the model.\n * @param principal - Copied verified actor.\n * @param name - Host-registered tool name.\n * @returns Exactly true permits disclosure; other results deny it.\n * @throws Host policy errors propagate into the execution outcome.\n * @example\n * ```typescript\n * import type { ToolAgentOptions } from '@alneas/eaos-server/execution/tool-agent';\n * export function disclosurePolicy(policy: ToolAgentOptions['disclose']) { return policy; }\n * ```\n */\n disclose(principal: ExecutionPrincipal, name: string): Promise<boolean>\n /**\n * Check exact resource/input permission before execution and before result disclosure.\n * @param principal - Copied verified actor; callback mutation cannot change the trusted identity.\n * @param call - Untrusted model request with correlated ID, name and arguments.\n * @returns Exactly true admits the call; it does not approve a handoff for execution.\n * @throws Host policy errors propagate into the execution outcome.\n * @example\n * ```typescript\n * import type { ToolAgentOptions } from '@alneas/eaos-server/execution/tool-agent';\n * export function callPolicy(policy: ToolAgentOptions['authorizeCall']) { return policy; }\n * ```\n */\n authorizeCall(principal: ExecutionPrincipal, call: ActionToolCall): Promise<boolean>\n /** Maximum model rounds; default 6, allowed integers 1–20. */\n maxRounds?: number\n /** Maximum automatic Action calls per run; default 10, allowed integers 1–100. */\n maxCalls?: number\n}\n/** Final in-memory conversational outcome, separate from Appkit execution status.\n * @see createToolAgent\n */\nexport interface ToolAgentResult {\n /** Completed chat, unexecuted handoff, bounded stop, or an Action validation/execution failure. */\n status: 'completed' | 'handoff' | 'limited' | 'tool-error'\n /** Detached correlated chat history, including only authorized projected tool results. */\n messages: AIChatMessage[]\n /** Unexecuted requests; the host must validate them through its existing Action/Proposal review path. */\n pending: ActionToolCall[]\n /** Number of attempted automatic Action calls, including a returned Action failure. */\n callsExecuted: number\n}\n/**\n * Orchestrate bounded model rounds through existing Appkit Action/Execution and scoped EAOS chat.\n * @param options - Current session/disclosure/call policies, Appkit adapter and chat/round/call limits.\n * @returns Single-flight run, cancel, close and summary subscription methods backed by Appkit ExecutionSession.\n * @throws Invalid policies or round/call limits reject construction. Concurrent/closed runs reject through\n * Appkit; asynchronous authorization/provider failures become failed execution outcomes. Cancellation is\n * cooperative and does not roll back previously completed Action effects.\n * @remarks Only explicitly host-verified read tools execute automatically. A batch containing any handoff\n * returns all its calls without executing them. No durable command engine, approval grant or transaction\n * is created; retained tool-call/result history and descriptors are reauthorized at the exact adapter\n * boundary after chat governance, including caller-supplied history and guard substitutions. Approved writes belong to the host's existing proposal/approval and owning command service.\n * @example\n * ```typescript\n * import { createToolAgent, type ToolAgentOptions } from '@alneas/eaos-server/execution/tool-agent';\n * export function connectAgent(options: ToolAgentOptions) { return createToolAgent(options); }\n * ```\n */\nexport function createToolAgent(options: ToolAgentOptions) {\n const { session: makeSession, disclose, authorizeCall, authorize } = options\n const maxRounds = options.maxRounds ?? 6, maxCalls = options.maxCalls ?? 10, maxChars = options.maxInputChars ?? 200000\n if (typeof makeSession !== 'function' || typeof disclose !== 'function' || typeof authorizeCall !== 'function' || typeof authorize !== 'function' || !Number.isSafeInteger(maxRounds) || maxRounds < 1 || maxRounds > 20 || !Number.isSafeInteger(maxCalls) || maxCalls < 1 || maxCalls > 100) throw new Error('Agent policy and valid limits required')\n // Snapshot chat settings, while preserving the provider's existing transport implementation.\n const chatOptions = { ...options, parameters: structuredClone(options.parameters), modelAdapters: options.modelAdapters && Object.freeze({...options.modelAdapters}) }\n const execution = createExecutionSession()\n return {\n /**\n * Request cooperative cancellation of the current Appkit execution.\n * @returns No value; Appkit marks active work cancelling without rolling back completed effects.\n * @example\n * ```typescript\n * import { createToolAgent } from '@alneas/eaos-server/execution/tool-agent';\n * export function cancel(agent: ReturnType<typeof createToolAgent>) { return agent.cancel(); }\n * ```\n */\n cancel: () => execution.cancel(),\n /**\n * Read Appkit's summary-only in-memory execution history.\n * @returns Appkit execution summaries; raw model inputs/results are not stored in these summaries.\n * @example\n * ```typescript\n * import { createToolAgent } from '@alneas/eaos-server/execution/tool-agent';\n * export function snapshot(agent: ReturnType<typeof createToolAgent>) { return agent.getSnapshot(); }\n * ```\n */\n getSnapshot: () => execution.getSnapshot(),\n /**\n * Subscribe to Appkit execution summary changes.\n * @param listener - Callback notified when execution state changes; do not expose raw secrets in UI callbacks.\n * @returns Unsubscribe function owned by the subscribing host.\n * @example\n * ```typescript\n * import { createToolAgent } from '@alneas/eaos-server/execution/tool-agent';\n * export function observe(agent: ReturnType<typeof createToolAgent>, listener: () => void) { return agent.subscribe(listener); }\n * ```\n */\n subscribe: (listener: () => void) => execution.subscribe(listener),\n /**\n * Close the Appkit session and request cooperative cancellation.\n * @returns No value; the session no longer admits new runs.\n * @example\n * ```typescript\n * import { createToolAgent } from '@alneas/eaos-server/execution/tool-agent';\n * export function close(agent: ReturnType<typeof createToolAgent>) { agent.close(); }\n * ```\n */\n close: () => execution.close(),\n /**\n * Run a single authorized model/Action conversation.\n * @param principal - Verified current tenant/user identity, copied before host callbacks.\n * @param input - Detached initial messages and optional cooperative cancellation signal.\n * @returns Appkit execution outcome containing a ToolAgentResult on success; failed/cancelled outcomes omit it.\n * @throws Appkit rejects concurrent or closed session admission; run failures otherwise become outcomes.\n * @example\n * ```typescript\n * import { createToolAgent } from '@alneas/eaos-server/execution/tool-agent';\n * export function run(agent: ReturnType<typeof createToolAgent>, ...args: Parameters<typeof agent.run>) { return agent.run(...args); }\n * ```\n */\n async run(principal: ExecutionPrincipal, input: { messages: readonly AIChatMessage[]; signal?: AbortSignal }) {\n const p = structuredClone(principal), messages = structuredClone(input.messages) as AIChatMessage[]\n return execution.run('AI tool session', async context => {\n const externalAbort = () => execution.cancel()\n input.signal?.addEventListener('abort', externalAbort, { once: true })\n if (input.signal?.aborted) externalAbort()\n let bridge: ReturnType<typeof createActionToolBridge> | undefined\n let callsExecuted = 0\n const check = async () => {\n if (context.signal.aborted) throw new DOMException('Agent cancelled', 'AbortError')\n if (!p || [p.tenantId, p.userId].some(v => typeof v !== 'string' || !v.trim()) || await authorize(structuredClone(p), 'model:chat') !== true) throw new Error('Agent access denied')\n if (context.signal.aborted) throw new DOMException('Agent cancelled', 'AbortError')\n if (!Array.isArray(messages) || !messages.length || messages.length > 1000 || JSON.stringify(messages).length > maxChars) throw new Error('Agent history limit')\n }\n const allowed = async (call: ActionToolCall) => {\n await check()\n if (await disclose(structuredClone(p), call.name) !== true || await authorizeCall(structuredClone(p), structuredClone(call)) !== true) throw new Error('Agent tool access denied')\n await check()\n }\n const result = (status: ToolAgentResult['status'], pending: ActionToolCall[] = []): ToolAgentResult => ({ status, messages: structuredClone(messages), pending: structuredClone(pending), callsExecuted })\n try {\n await check()\n const session = await makeSession(structuredClone(p))\n await check()\n if (!Array.isArray(session.tools) || session.tools.length > 100 || session.tools.some(tool => !['read', 'handoff'].includes(tool.mode))) throw new Error('Invalid agent tool policy')\n const modes = new Map(session.tools.map(tool => [tool.binding.name, tool.mode]))\n const registrations = new Map(session.tools.filter(tool => tool.binding.kind === 'action').map(tool => {\n const binding = tool.binding as Extract<ActionToolBinding, { kind: 'action' }>\n return [binding.name, { id: binding.actionId, action: session.registry.getAction(binding.actionId) }]\n }))\n bridge = createActionToolBridge(session.registry, { tools: session.tools.map(tool => tool.binding), maxCalls })\n const activeBridge = bridge\n const authorizeHistory = async (history: readonly AIChatMessage[]) => {\n const prior = new Map<string, ActionToolCall>(), results = new Set<string>()\n for (const message of history) for (const part of message.parts) {\n if (part.type === 'tool-call') {\n if (prior.has(part.callId) || !modes.has(part.name)) throw new Error('Agent retained tool history is invalid')\n const call = {callId:part.callId,name:part.name,arguments:part.input}\n prior.set(call.callId,call)\n await allowed(call)\n } else if (part.type === 'tool-result') {\n const call = prior.get(part.callId)\n if (!call || call.name !== part.name || results.has(part.callId)) throw new Error('Agent retained tool result has no unique authorized call')\n results.add(part.callId)\n await allowed(call)\n }\n }\n }\n // A policy decorator checks the exact final request, including host-guard substitutions.\n // The existing Appkit adapter still owns transport, encoding and parsing.\n const authorizeAdapter = (transport: AIChatAdapter): AIChatAdapter => ({\n id:transport.id,capabilities:transport.capabilities,\n async *stream(request) {\n for (const descriptor of request.tools ?? []) {\n if (!modes.has(descriptor.name) || await disclose(structuredClone(p),descriptor.name) !== true) throw new Error('Agent tool descriptor disclosure denied')\n }\n await check()\n await authorizeHistory(request.messages)\n request.signal?.throwIfAborted()\n yield* transport.stream(request)\n },\n })\n const chat = createChatClient({ ...chatOptions,\n authorize:async (actor,operation) => {\n if (await authorize(actor,operation) !== true) return false\n await authorizeHistory(messages)\n return true\n },\n adapter:authorizeAdapter(chatOptions.adapter),\n ...(chatOptions.modelAdapters ? {modelAdapters:Object.fromEntries(Object.entries(chatOptions.modelAdapters).map(([model,adapter])=>[model,authorizeAdapter(adapter)]))} : {}),\n tools: async () => {\n const tools: ActionToolDescriptor[] = []\n for (const tool of activeBridge.listTools()) if (await disclose(structuredClone(p), tool.name) === true) tools.push(tool)\n return tools\n },\n })\n for (let round = 0; round < maxRounds; round++) {\n await check()\n const answer = await chat.complete(p, { messages, signal: context.signal, tools: 'catalog' })\n messages.push(answer.message)\n await check()\n if (answer.finishReason === 'stop') return result('completed')\n const calls = answer.message.parts.filter((part): part is Extract<AIChatPart, { type: 'tool-call' }> => part.type === 'tool-call').map(part => ({ callId: part.callId, name: part.name, arguments: part.input }))\n for (const call of calls) await allowed(call)\n if (calls.some(call => modes.get(call.name) === 'handoff')) return result('handoff', calls)\n if (callsExecuted + calls.length > maxCalls || round + 1 === maxRounds) return result('limited', calls)\n for (let index = 0; index < calls.length; index++) {\n const call = calls[index]\n await allowed(call)\n const registration = registrations.get(call.name)\n if (registration && session.registry.getAction(registration.id) !== registration.action) throw new Error('Agent action registration changed')\n const output = await activeBridge.execute(call, context)\n callsExecuted++\n await allowed(call)\n messages.push({ id: crypto.randomUUID(), role: 'tool', parts: [{ type: 'tool-result', callId: call.callId, name: call.name, output: output.ok ? output.data : { code: output.code, error: output.error }, ...(!output.ok ? { isError: true } : {}) }] })\n await check()\n context.reportProgress({ completed: callsExecuted, total: maxCalls })\n if (!output.ok) return result('tool-error', calls.slice(index + 1))\n }\n }\n return result('limited')\n } finally { bridge?.close(); input.signal?.removeEventListener('abort', externalAbort) }\n })\n },\n }\n}\n"],"mappings":"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","names":[]}
|