@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.
Files changed (43) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.ja.md +28 -18
  3. package/README.md +8 -2
  4. package/dist/agentic/agent-jobs.d.ts +5 -1
  5. package/dist/agentic/autonomous-worker.d.ts +30 -3
  6. package/dist/agentic/autonomous-worker.js +2 -1
  7. package/dist/agentic/event-bridge.d.ts +6 -0
  8. package/dist/agentic/index.d.ts +7 -3
  9. package/dist/agentic/index.js +2 -1
  10. package/dist/agentic/local-runner.d.ts +6 -2
  11. package/dist/chunk-4BARRLJR.js +180 -0
  12. package/dist/chunk-4BARRLJR.js.map +1 -0
  13. package/dist/{chunk-THYUY5ZZ.js → chunk-F2J6IQ6I.js} +68 -25
  14. package/dist/chunk-F2J6IQ6I.js.map +1 -0
  15. package/dist/{chunk-6KV5CJBW.js → chunk-F4IITPGX.js} +5 -5
  16. package/dist/{chunk-DHQGNP4T.js → chunk-SDJNYPYK.js} +2 -2
  17. package/dist/{chunk-DHQGNP4T.js.map → chunk-SDJNYPYK.js.map} +1 -1
  18. package/dist/chunk-YMHVRBUU.js +199 -0
  19. package/dist/chunk-YMHVRBUU.js.map +1 -0
  20. package/dist/db-package/index.js +3 -3
  21. package/dist/engine.js +2 -2
  22. package/dist/execution/chat.d.ts +7 -0
  23. package/dist/execution/chat.js +7 -0
  24. package/dist/execution/chat.js.map +1 -0
  25. package/dist/execution/index.d.ts +294 -2
  26. package/dist/execution/index.js +10 -1
  27. package/dist/execution/index.js.map +1 -1
  28. package/dist/execution/tool-agent.d.ts +7 -0
  29. package/dist/execution/tool-agent.js +8 -0
  30. package/dist/execution/tool-agent.js.map +1 -0
  31. package/dist/index.d.ts +5 -1
  32. package/dist/index.js +4 -3
  33. package/dist/lifecycle-engine/backend-migration.js +1 -1
  34. package/dist/lifecycle-engine/baseline.js +1 -1
  35. package/dist/lifecycle-engine/index.js +1 -1
  36. package/dist/lifecycle-engine/platform/index.js +8 -8
  37. package/dist/sql-lifecycle/index.d.ts +1 -1
  38. package/docs/api.md +809 -2
  39. package/docs/guide.md +44 -0
  40. package/docs/index.md +6 -2
  41. package/package.json +12 -3
  42. package/dist/chunk-THYUY5ZZ.js.map +0 -1
  43. /package/dist/{chunk-6KV5CJBW.js.map → chunk-F4IITPGX.js.map} +0 -0
@@ -1,3 +1,6 @@
1
+ import {
2
+ createChatClient
3
+ } from "./chunk-YMHVRBUU.js";
1
4
  import {
2
5
  createCommandAgentExecutor,
3
6
  validateAgentRuntimePolicy
@@ -7,6 +10,7 @@ import {
7
10
  } from "./chunk-YABTQZDJ.js";
8
11
 
9
12
  // src/agentic/autonomous-worker.ts
13
+ import { createOpenAICompatibleChatAdapter } from "@alneas/appkit-core/ai/ai-chat";
10
14
  import { defaultRuntimePlacementPolicy, McpGatekeeper } from "@alneas/eaos-core";
11
15
  import { randomUUID } from "node:crypto";
12
16
  function inferRuntimeRole() {
@@ -20,6 +24,8 @@ var ServerAutonomousWorker = class {
20
24
  hermesAgentPath;
21
25
  litellmUrl;
22
26
  litellmModel;
27
+ litellmHeaders;
28
+ chatOptions;
23
29
  maxOutputChars;
24
30
  runtimePolicy;
25
31
  runtimeRole;
@@ -37,6 +43,8 @@ var ServerAutonomousWorker = class {
37
43
  this.hermesAgentPath = options?.hermesAgentBinaryPath || process.env.HERMES_AGENT_BIN_PATH || "hermes";
38
44
  this.litellmUrl = options?.litellmEndpoint || process.env.LITELLM_ENDPOINT || "http://localhost:4000/v1";
39
45
  this.litellmModel = options?.litellmModel || process.env.LITELLM_MODEL;
46
+ this.litellmHeaders = { ...options?.litellmHeaders };
47
+ this.chatOptions = { ...options?.chat, parameters: structuredClone(options?.chat?.parameters) };
40
48
  this.maxOutputChars = options?.maxOutputChars ?? 1e6;
41
49
  this.runtimePolicy = validateAgentRuntimePolicy(options?.runtimePolicy || defaultRuntimePlacementPolicy().ai.agentRuntime);
42
50
  this.runtimeRole = options?.runtimeRole || inferRuntimeRole();
@@ -48,9 +56,10 @@ var ServerAutonomousWorker = class {
48
56
  /**
49
57
  * Checks task limits and gatekeeper policy before dispatching one runtime attempt.
50
58
  * @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.
59
+ * @param execution - Optional cancellation signal for built-in shared chat tasks; does not change injected executor or process contracts.
51
60
  * @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.
52
61
  * @throws Can reject a throwing gatekeeper or malformed gatekeeper interaction before dispatch; runtime execution errors are normally returned as FAILED data.
53
- * @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 LiteLLM outputs are bounded by maxOutputChars; LiteLLM response bodies are parsed before text length is checked.
62
+ * @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.
54
63
  * @example
55
64
  * ```typescript
56
65
  * import { ServerAutonomousWorker, type ServerWorkerOptions } from "@alneas/eaos-server/agentic/autonomous-worker";
@@ -60,7 +69,7 @@ var ServerAutonomousWorker = class {
60
69
  * }
61
70
  * ```
62
71
  */
63
- async runTask(request) {
72
+ async runTask(request, execution = {}) {
64
73
  const startTime = Date.now();
65
74
  if (!request || [request.id, request.tenantId, request.userId, request.title, request.instructions].some((value) => typeof value !== "string" || !value.trim())) {
66
75
  return { taskId: typeof request?.id === "string" ? request.id : "unknown", status: "FAILED", error: "Invalid agent task request", durationMs: Date.now() - startTime };
@@ -115,7 +124,7 @@ var ServerAutonomousWorker = class {
115
124
  }
116
125
  if (frameworkManaged) this.activeTasks += 1;
117
126
  try {
118
- const output = await this.execute({ ...structuredClone(request), runtimePolicy: structuredClone(this.runtimePolicy) });
127
+ const output = await this.execute({ ...structuredClone(request), runtimePolicy: structuredClone(this.runtimePolicy) }, execution.signal);
119
128
  return {
120
129
  taskId: request.id,
121
130
  status: "COMPLETED",
@@ -134,12 +143,12 @@ var ServerAutonomousWorker = class {
134
143
  if (frameworkManaged) this.activeTasks -= 1;
135
144
  }
136
145
  }
137
- async execute(request) {
146
+ async execute(request, signal) {
138
147
  const injected = this.executors[request.workerType];
139
148
  if (injected) return this.boundOutput(await injected(structuredClone(request)));
140
149
  if (request.workerType === "goose") return this.executeHeadlessGoose(request);
141
150
  if (request.workerType === "hermes_agent") return this.executeHeadlessHermesAgent(request);
142
- if (request.workerType === "litellm") return this.executeLiteLlm(request);
151
+ if (request.workerType === "litellm") return this.executeLiteLlm(request, signal);
143
152
  throw new Error(`No executor configured for worker type '${request.workerType}'`);
144
153
  }
145
154
  /**
@@ -170,27 +179,61 @@ var ServerAutonomousWorker = class {
170
179
  /**
171
180
  * Execute a host-selected model through LiteLLM.
172
181
  */
173
- async executeLiteLlm(request) {
174
- if (!this.litellmModel) throw new Error("LiteLLM model is not configured");
175
- const endpoint = new URL(this.litellmUrl);
176
- if (!["http:", "https:"].includes(endpoint.protocol)) throw new Error("Invalid LiteLLM endpoint");
177
- endpoint.pathname = `${endpoint.pathname.replace(/\/$/, "")}/chat/completions`;
178
- const response = await this.fetchImpl(endpoint, {
179
- method: "POST",
180
- headers: { "Content-Type": "application/json" },
181
- body: JSON.stringify({
182
+ async executeLiteLlm(request, signal) {
183
+ const configured = this.chatOptions;
184
+ let adapter = configured.adapter;
185
+ if (!adapter) {
186
+ if (!this.litellmModel) throw new Error("LiteLLM model is not configured");
187
+ const endpoint = new URL(this.litellmUrl);
188
+ if (!["http:", "https:"].includes(endpoint.protocol)) throw new Error("Invalid LiteLLM endpoint");
189
+ endpoint.pathname = `${endpoint.pathname.replace(/\/$/, "")}/chat/completions`;
190
+ adapter = createOpenAICompatibleChatAdapter({
191
+ api: endpoint.href,
182
192
  model: this.litellmModel,
183
- messages: [{ role: "user", content: request.instructions }],
184
- metadata: { tenantId: request.tenantId, taskId: request.id }
185
- }),
186
- signal: AbortSignal.timeout(request.timeoutMs ?? 6e4),
187
- redirect: "error"
193
+ headers: this.litellmHeaders,
194
+ maxResponseChars: Math.min(1e7, this.maxOutputChars * 6 + 65536),
195
+ fetch: async (input, init) => {
196
+ const response = await this.fetchImpl(input, { ...init, redirect: "error" });
197
+ if (!response.ok) {
198
+ try {
199
+ void response.body?.cancel().catch(() => {
200
+ });
201
+ } catch {
202
+ }
203
+ throw new Error(`LiteLLM request failed (${response.status})`);
204
+ }
205
+ return response;
206
+ }
207
+ });
208
+ }
209
+ const metadata = configured.parameters?.metadata;
210
+ const timeout = request.timeoutMs ?? 6e4;
211
+ const chat = createChatClient({
212
+ ...configured,
213
+ adapter,
214
+ timeoutMs: Math.min(timeout, configured.timeoutMs ?? timeout),
215
+ maxInputChars: configured.maxInputChars ?? 7e6,
216
+ maxOutputChars: Math.min(1e7, configured.maxOutputChars ?? this.maxOutputChars * 6 + 65536),
217
+ parameters: { ...configured.parameters, metadata: {
218
+ ...metadata && typeof metadata === "object" && !Array.isArray(metadata) ? metadata : {},
219
+ tenantId: request.tenantId,
220
+ taskId: request.id
221
+ } },
222
+ governance: { ...configured.governance, sessionId: configured.governance?.sessionId ?? request.id },
223
+ authorize: async (principal, operation) => {
224
+ if (principal.tenantId !== request.tenantId || principal.userId !== request.userId) return false;
225
+ if (configured.authorize && await configured.authorize(principal, operation) !== true) return false;
226
+ const decision = this.gatekeeper.validateCall({ toolName: "server_agent_litellm", userRoles: ["agent", "server_bot"], tenantId: principal.tenantId });
227
+ return decision.allowed && !decision.requireHumanApproval;
228
+ }
229
+ });
230
+ const completed = await chat.complete({ tenantId: request.tenantId, userId: request.userId }, {
231
+ messages: [{ id: request.id, role: "user", parts: [{ type: "text", text: request.instructions }] }],
232
+ tools: "none",
233
+ signal
188
234
  });
189
- if (!response.ok) throw new Error(`LiteLLM request failed (${response.status})`);
190
- const body = await response.json();
191
- const output = body.choices?.[0]?.message?.content;
192
- if (typeof output !== "string") throw new Error("LiteLLM returned no assistant content");
193
- return this.boundOutput(output);
235
+ if (completed.message.parts.some((part) => part.type !== "text")) throw new Error("LiteLLM returned no assistant content");
236
+ return this.boundOutput(completed.message.parts.map((part) => part.type === "text" ? part.text : "").join(""));
194
237
  }
195
238
  boundOutput(output) {
196
239
  if (output.length > this.maxOutputChars) throw new Error("Agent output exceeds configured limit");
@@ -201,4 +244,4 @@ var ServerAutonomousWorker = class {
201
244
  export {
202
245
  ServerAutonomousWorker
203
246
  };
204
- //# sourceMappingURL=chunk-THYUY5ZZ.js.map
247
+ //# sourceMappingURL=chunk-F2J6IQ6I.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/agentic/autonomous-worker.ts"],"sourcesContent":["import {createOpenAICompatibleChatAdapter, type AIChatAdapter} from '@alneas/appkit-core/ai/ai-chat'\nimport {createChatClient, type ChatClientOptions} from '../execution/chat'\nimport { defaultRuntimePlacementPolicy, McpGatekeeper, type AgentRuntimeResourcePolicy } from '@alneas/eaos-core'\nimport { ServerAgentExecutionError, type ServerAgentExecutor, type ServerAgentTaskRequest, type ServerAgentTaskResult, type ServerAgentWorkerType } from './types'\nimport { randomUUID } from 'node:crypto'\nimport { createCommandAgentExecutor, validateAgentRuntimePolicy } from './executor'\n\n/**\n * Host composition of the shared chat path for built-in model tasks.\n * @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.\n * @see ServerWorkerOptions for complete worker configuration.\n */\nexport interface ServerWorkerChatOptions extends Omit<ChatClientOptions, 'adapter' | 'authorize' | 'tools'> {\n /** Optional host adapter; omission uses Appkit's OpenAI-compatible LiteLLM transport. */\n adapter?: AIChatAdapter\n /** Optional live Host authorization, combined with the worker gatekeeper before and after asynchronous work. */\n authorize?: ChatClientOptions['authorize']\n}\n\n/**\n * Trusted gatekeeper, runtime endpoints/adapters, and execution limits for {@link ServerAutonomousWorker}.\n */\nexport interface ServerWorkerOptions {\n /** Host security/approval policies; defaults to a new McpGatekeeper. */\n gatekeeper?: McpGatekeeper\n /** Trusted executable path; defaults to GOOSE_BIN_PATH or goose. */\n gooseBinaryPath?: string\n /** Trusted executable path; defaults to HERMES_AGENT_BIN_PATH or hermes. */\n hermesAgentBinaryPath?: string\n /** Host LiteLLM base URL; defaults to LITELLM_ENDPOINT or http://localhost:4000/v1. */\n litellmEndpoint?: string\n /** Host model identifier; defaults to LITELLM_MODEL and is required for built-in LiteLLM execution. */\n litellmModel?: string\n /** Host-owned provider headers; captured at construction and never read from task/model input. */\n litellmHeaders?: Readonly<Record<string, string>>\n /** Optional shared chat model routing, live authorization, limits, guards, usage, budget and observability. */\n chat?: ServerWorkerChatOptions\n /** Combined command output/string result ceiling, safe integer 1–10000000; defaults to 1000000. */\n maxOutputChars?: number\n /** Framework default is safe for the ARM agent host. Host adapters may tighten it. */\n runtimePolicy?: AgentRuntimeResourcePolicy\n /** Built-in Goose/Hermes execution is permitted only on the AI placement. */\n runtimeRole?: ServerRuntimeRole\n /** Host fetch implementation for built-in LiteLLM; defaults to global fetch. */\n fetch?: typeof fetch\n /** Host/plugin adapters for coding agents and other external runtimes. */\n executors?: Partial<Record<ServerAgentWorkerType, ServerAgentExecutor>>\n}\n\n/**\n * Host placement role controlling whether built-in Goose/Hermes processes may run locally.\n * @see ServerAutonomousWorker.\n */\nexport type ServerRuntimeRole = 'edge' | 'application-worker' | 'ai'\n\nfunction inferRuntimeRole(): ServerRuntimeRole {\n const configured = process.env.EAOS_RUNTIME_ROLE\n if (configured === 'edge' || configured === 'application-worker' || configured === 'ai') return configured\n // The supported three-host topology places the AI runtime on the ARM host.\n // Unknown x64 hosts therefore fail closed as application-worker hosts.\n return process.arch === 'arm64' ? 'ai' : 'application-worker'\n}\n\n/**\n * Admits and executes host agent tasks through a gatekeeper and bounded runtime adapters.\n * @remarks This class runs only when runTask is called; it installs no scheduler. The host authenticates tenant/user claims before admission. Framework-managed tasks share a per-instance concurrency counter; injected executors own scheduling and are exempt from it. Built-in Goose/Hermes require the ai role and Node process/systemd support. Queue persistence, approvals, retries, and side-effect idempotency belong to the host.\n * @example\n * ```typescript\n * import { ServerAutonomousWorker, type ServerWorkerOptions } from \"@alneas/eaos-server/agentic/autonomous-worker\";\n * export function worker(options: ServerWorkerOptions) { return new ServerAutonomousWorker(options); }\n * ```\n */\nexport class ServerAutonomousWorker {\n private gatekeeper: McpGatekeeper\n private goosePath: string\n private hermesAgentPath: string\n private litellmUrl: string\n private litellmModel?: string\n private litellmHeaders: Record<string, string>\n private chatOptions: ServerWorkerChatOptions\n private maxOutputChars: number\n private runtimePolicy: AgentRuntimeResourcePolicy\n private runtimeRole: ServerRuntimeRole\n private activeTasks = 0\n private fetchImpl: typeof fetch\n private executors: Partial<Record<ServerAgentWorkerType, ServerAgentExecutor>>\n\n /**\n * Captures runtime settings and validates resource policy, role, and output ceiling.\n * @param options - Trusted host configuration; omitted gatekeeper uses a new McpGatekeeper and runtime role uses EAOS_RUNTIME_ROLE, then ai on arm64 or application-worker otherwise.\n * @throws Invalid resource policy, role, or output limit.\n */\n constructor(options?: ServerWorkerOptions) {\n this.gatekeeper = options?.gatekeeper || new McpGatekeeper()\n this.goosePath = options?.gooseBinaryPath || process.env.GOOSE_BIN_PATH || 'goose'\n this.hermesAgentPath = options?.hermesAgentBinaryPath || process.env.HERMES_AGENT_BIN_PATH || 'hermes'\n this.litellmUrl = options?.litellmEndpoint || process.env.LITELLM_ENDPOINT || 'http://localhost:4000/v1'\n this.litellmModel = options?.litellmModel || process.env.LITELLM_MODEL\n this.litellmHeaders = {...options?.litellmHeaders}\n this.chatOptions = {...options?.chat, parameters: structuredClone(options?.chat?.parameters)}\n this.maxOutputChars = options?.maxOutputChars ?? 1_000_000\n this.runtimePolicy = validateAgentRuntimePolicy(options?.runtimePolicy || defaultRuntimePlacementPolicy().ai.agentRuntime)\n this.runtimeRole = options?.runtimeRole || inferRuntimeRole()\n if (!['edge', 'application-worker', 'ai'].includes(this.runtimeRole)) throw new Error('Invalid agent runtime role')\n this.fetchImpl = options?.fetch || fetch\n this.executors = options?.executors || {}\n if (!Number.isSafeInteger(this.maxOutputChars) || this.maxOutputChars < 1 || this.maxOutputChars > 10_000_000) throw new Error('Invalid worker output limit')\n }\n\n /**\n * Checks task limits and gatekeeper policy before dispatching one runtime attempt.\n * @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.\n * @param execution - Optional cancellation signal for built-in shared chat tasks; does not change injected executor or process contracts.\n * @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.\n * @throws Can reject a throwing gatekeeper or malformed gatekeeper interaction before dispatch; runtime execution errors are normally returned as FAILED data.\n * @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.\n * @example\n * ```typescript\n * import { ServerAutonomousWorker, type ServerWorkerOptions } from \"@alneas/eaos-server/agentic/autonomous-worker\";\n * import type { ServerAgentTaskRequest } from \"@alneas/eaos-server/agentic/types\";\n * export async function execute(options: ServerWorkerOptions, request: ServerAgentTaskRequest) {\n * return new ServerAutonomousWorker(options).runTask(request);\n * }\n * ```\n */\n async runTask(request: ServerAgentTaskRequest, execution: {\n /** Cooperatively cancel built-in shared chat. Injected executors and Goose/Hermes retain their own cancellation contracts. */\n signal?: AbortSignal\n } = {}): Promise<ServerAgentTaskResult> {\n const startTime = Date.now()\n\n if (!request || [request.id, request.tenantId, request.userId, request.title, request.instructions].some(value => typeof value !== 'string' || !value.trim())) {\n return { taskId: typeof request?.id === 'string' ? request.id : 'unknown', status: 'FAILED', error: 'Invalid agent task request', durationMs: Date.now() - startTime }\n }\n if (request.instructions.length > 1_000_000 || request.title.length > 500 || request.timeoutMs !== undefined && (!Number.isSafeInteger(request.timeoutMs) || request.timeoutMs < 1 || request.timeoutMs > 3_600_000)) {\n return { taskId: request.id, status: 'FAILED', error: 'Agent task exceeds configured limits', durationMs: Date.now() - startTime }\n }\n\n // 1. Evaluate security and gatekeeper policies\n const policy = this.gatekeeper.validateCall({\n toolName: `server_agent_${request.workerType}`,\n userRoles: ['agent', 'server_bot'],\n tenantId: request.tenantId,\n })\n\n if (!policy.allowed) {\n return {\n taskId: request.id,\n status: 'FAILED',\n error: `Task execution blocked by security policy: ${policy.reason}`,\n riskLevel: policy.riskLevel,\n durationMs: Date.now() - startTime,\n }\n }\n\n if (policy.requireHumanApproval) {\n return {\n taskId: request.id,\n status: 'PENDING_APPROVAL',\n approvalTicketId: randomUUID(),\n approvalLevel: policy.approvalLevel,\n riskLevel: policy.riskLevel,\n durationMs: Date.now() - startTime,\n }\n }\n\n // Explicitly injected executors are host-owned adapters and may implement\n // their own queue/scheduler. The framework-managed Goose/Hermes path is\n // bounded by the default policy so a forgotten host setting cannot create\n // unbounded local agent concurrency.\n const frameworkManaged = !this.executors[request.workerType]\n if (frameworkManaged && (request.workerType === 'goose' || request.workerType === 'hermes_agent') && this.runtimeRole !== 'ai') {\n return {\n taskId: request.id,\n status: 'FAILED',\n error: `Built-in ${request.workerType} execution is restricted to the AI runtime placement`,\n failureCode: 'AGENT_UNAVAILABLE',\n retryable: true,\n durationMs: Date.now() - startTime,\n }\n }\n if (frameworkManaged && this.activeTasks >= this.runtimePolicy.maxConcurrent) {\n return {\n taskId: request.id,\n status: 'FAILED',\n error: 'Agent runtime concurrency limit reached',\n failureCode: 'AGENT_UNAVAILABLE',\n retryable: true,\n durationMs: Date.now() - startTime,\n }\n }\n\n // 2. Dispatch according to worker type\n if (frameworkManaged) this.activeTasks += 1\n try {\n const output = await this.execute({ ...structuredClone(request), runtimePolicy: structuredClone(this.runtimePolicy) }, execution.signal)\n return {\n taskId: request.id,\n status: 'COMPLETED',\n output,\n durationMs: Date.now() - startTime,\n }\n } catch (err) {\n return {\n taskId: request.id,\n status: 'FAILED',\n error: (err as Error).message,\n ...(err instanceof ServerAgentExecutionError ? { failureCode: err.failureCode, retryable: err.retryable } : {}),\n durationMs: Date.now() - startTime,\n }\n } finally {\n if (frameworkManaged) this.activeTasks -= 1\n }\n }\n\n private async execute(request: ServerAgentTaskRequest, signal?: AbortSignal): Promise<string> {\n const injected = this.executors[request.workerType]\n if (injected) return this.boundOutput(await injected(structuredClone(request)))\n if (request.workerType === 'goose') return this.executeHeadlessGoose(request)\n if (request.workerType === 'hermes_agent') return this.executeHeadlessHermesAgent(request)\n if (request.workerType === 'litellm') return this.executeLiteLlm(request, signal)\n throw new Error(`No executor configured for worker type '${request.workerType}'`)\n }\n\n /**\n * Execute Goose in headless batch mode\n */\n private async executeHeadlessGoose(request: ServerAgentTaskRequest): Promise<string> {\n return createCommandAgentExecutor({\n command: this.goosePath,\n buildArgs: task => ['run', '--text', task.instructions],\n includeProcessEnv: true,\n maxOutputChars: this.maxOutputChars,\n sandbox: { mode: 'auto', policy: this.runtimePolicy },\n })(request)\n }\n\n /**\n * Execute NousResearch Hermes Agent in headless mode (-z / non-interactive)\n * Hermes Agent provides persistent cross-session memory and self-improving skill extraction.\n */\n private async executeHeadlessHermesAgent(request: ServerAgentTaskRequest): Promise<string> {\n return createCommandAgentExecutor({\n command: this.hermesAgentPath,\n buildArgs: task => ['run', '-z', task.instructions],\n includeProcessEnv: true,\n maxOutputChars: this.maxOutputChars,\n sandbox: { mode: 'auto', policy: this.runtimePolicy },\n })(request)\n }\n\n /**\n * Execute a host-selected model through LiteLLM.\n */\n private async executeLiteLlm(request: ServerAgentTaskRequest, signal?: AbortSignal): Promise<string> {\n const configured = this.chatOptions\n let adapter = configured.adapter\n if (!adapter) {\n if (!this.litellmModel) throw new Error('LiteLLM model is not configured')\n const endpoint = new URL(this.litellmUrl)\n if (!['http:', 'https:'].includes(endpoint.protocol)) throw new Error('Invalid LiteLLM endpoint')\n endpoint.pathname = `${endpoint.pathname.replace(/\\/$/, '')}/chat/completions`\n adapter = createOpenAICompatibleChatAdapter({\n api: endpoint.href, model: this.litellmModel, headers: this.litellmHeaders,\n maxResponseChars: Math.min(10_000_000, this.maxOutputChars * 6 + 65_536),\n fetch: async (input, init) => {\n const response = await this.fetchImpl(input, {...init, redirect: 'error'})\n if (!response.ok) {\n try { void response.body?.cancel().catch(() => {}) } catch { /* Preserve the provider status while releasing unread bodies. */ }\n throw new Error(`LiteLLM request failed (${response.status})`)\n }\n return response\n },\n })\n }\n const metadata = configured.parameters?.metadata\n const timeout = request.timeoutMs ?? 60_000\n const chat = createChatClient({\n ...configured, adapter,\n timeoutMs: Math.min(timeout, configured.timeoutMs ?? timeout),\n maxInputChars: configured.maxInputChars ?? 7_000_000,\n maxOutputChars: Math.min(10_000_000, configured.maxOutputChars ?? this.maxOutputChars * 6 + 65_536),\n parameters: {...configured.parameters, metadata: {\n ...(metadata && typeof metadata === 'object' && !Array.isArray(metadata) ? metadata : {}),\n tenantId: request.tenantId, taskId: request.id,\n }},\n governance: {...configured.governance, sessionId: configured.governance?.sessionId ?? request.id},\n authorize: async (principal, operation) => {\n if (principal.tenantId !== request.tenantId || principal.userId !== request.userId) return false\n if (configured.authorize && await configured.authorize(principal, operation) !== true) return false\n const decision = this.gatekeeper.validateCall({toolName: 'server_agent_litellm', userRoles: ['agent', 'server_bot'], tenantId: principal.tenantId})\n return decision.allowed && !decision.requireHumanApproval\n },\n })\n const completed = await chat.complete({tenantId: request.tenantId, userId: request.userId}, {\n messages: [{id: request.id, role: 'user', parts: [{type: 'text', text: request.instructions}]}],\n tools: 'none', signal,\n })\n if (completed.message.parts.some(part => part.type !== 'text')) throw new Error('LiteLLM returned no assistant content')\n return this.boundOutput(completed.message.parts.map(part => part.type === 'text' ? part.text : '').join(''))\n }\n\n private boundOutput(output: string): string {\n if (output.length > this.maxOutputChars) throw new Error('Agent output exceeds configured limit')\n return output\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,3 +1,7 @@
1
+ import {
2
+ createLifecycleGuard,
3
+ resolveLifecycleBackend
4
+ } from "./chunk-L6PMAEMB.js";
1
5
  import {
2
6
  createAuthMiddleware
3
7
  } from "./chunk-XIEY2OF4.js";
@@ -10,10 +14,6 @@ import {
10
14
  import {
11
15
  createHealthRouter
12
16
  } from "./chunk-R4ADP2DC.js";
13
- import {
14
- createLifecycleGuard,
15
- resolveLifecycleBackend
16
- } from "./chunk-L6PMAEMB.js";
17
17
  import {
18
18
  createMcpRouter
19
19
  } from "./chunk-VF5YDZJC.js";
@@ -218,4 +218,4 @@ export {
218
218
  ErpEngine,
219
219
  createErpEngine
220
220
  };
221
- //# sourceMappingURL=chunk-6KV5CJBW.js.map
221
+ //# sourceMappingURL=chunk-F4IITPGX.js.map
@@ -7,7 +7,7 @@ import { createHash } from "node:crypto";
7
7
  import { satisfies, valid, validRange, lt } from "semver";
8
8
 
9
9
  // package.json
10
- var version = "0.1.0";
10
+ var version = "0.2.0";
11
11
 
12
12
  // src/lifecycle-engine/backend-migration.ts
13
13
  function text(value, name, max = 256) {
@@ -767,4 +767,4 @@ export {
767
767
  assertBackendMigrationVerification,
768
768
  assertBackendMigrationCutover
769
769
  };
770
- //# sourceMappingURL=chunk-DHQGNP4T.js.map
770
+ //# sourceMappingURL=chunk-SDJNYPYK.js.map