agent-orchestrator-mcp-server 0.8.9 → 0.8.10

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-orchestrator-mcp-server",
3
- "version": "0.8.9",
3
+ "version": "0.8.10",
4
4
  "description": "Local implementation of agent-orchestrator MCP server",
5
5
  "main": "build/index.js",
6
6
  "type": "module",
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * A client for interacting with the Agent Orchestrator REST API.
5
5
  */
6
- import type { Session, Log, SubagentTranscript, SessionsResponse, SearchSessionsResponse, SessionActionResponse, LogsResponse, SubagentTranscriptsResponse, CreateSessionRequest, UpdateSessionRequest, CreateLogRequest, UpdateLogRequest, CreateSubagentTranscriptRequest, UpdateSubagentTranscriptRequest, SessionStatus, LogLevel, SubagentStatus, MCPServerInfo, AgentRootInfo, ConfigsResponse, SendPushNotificationResponse, EnqueuedMessage, EnqueuedMessagesResponse, EnqueuedMessageInterruptResponse, EnqueuedMessageStatus, Category, CategoriesResponse, CreateCategoryRequest, UpdateCategoryRequest, SetSessionCategoryResponse, Trigger, TriggerType, TriggerStatus, TriggersResponse, TriggerResponse, TriggerChannelsResponse, CreateTriggerRequest, UpdateTriggerRequest, Notification, NotificationsResponse, NotificationBadgeResponse, NotificationMarkAllReadResponse, NotificationDismissAllReadResponse, HealthReport, HealthActionResponse, CliStatusResponse, CliActionResponse, ForkSessionResponse, RefreshSessionResponse, RefreshAllSessionsResponse, BulkArchiveResponse, TranscriptResponse, TranscriptArchiveStatusResponse, ElicitationActionType, ElicitationResponse } from '../types.js';
6
+ import type { Session, Log, SubagentTranscript, SessionsResponse, SearchSessionsResponse, SessionActionResponse, LogsResponse, SubagentTranscriptsResponse, CreateSessionRequest, UpdateSessionRequest, CreateLogRequest, UpdateLogRequest, CreateSubagentTranscriptRequest, UpdateSubagentTranscriptRequest, SessionStatus, LogLevel, SubagentStatus, MCPServerInfo, AgentRootInfo, ConfigsResponse, SendPushNotificationResponse, EnqueuedMessage, EnqueuedMessagesResponse, EnqueuedMessageInterruptResponse, EnqueuedMessageStatus, Category, CategoriesResponse, CreateCategoryRequest, UpdateCategoryRequest, SetSessionCategoryResponse, Trigger, TriggerType, TriggerStatus, TriggersResponse, TriggerResponse, TriggerChannelsResponse, TriggerConditionAttributes, TriggerConditionType, CreateTriggerRequest, UpdateTriggerRequest, Notification, NotificationsResponse, NotificationBadgeResponse, NotificationMarkAllReadResponse, NotificationDismissAllReadResponse, HealthReport, HealthActionResponse, CliStatusResponse, CliActionResponse, ForkSessionResponse, RefreshSessionResponse, RefreshAllSessionsResponse, BulkArchiveResponse, TranscriptResponse, TranscriptArchiveStatusResponse, ElicitationActionType, ElicitationResponse } from '../types.js';
7
7
  /** Raw agent root shape as returned by the Rails API */
8
8
  export interface RawAgentRoot {
9
9
  name: string;
@@ -25,6 +25,14 @@ export interface RawAgentRoot {
25
25
  * as they are not needed by MCP clients.
26
26
  */
27
27
  export declare function mapAgentRoot(raw: RawAgentRoot): AgentRootInfo;
28
+ /**
29
+ * Folds the ergonomic top-level `trigger_type` + `configuration` shape into the
30
+ * REST API's nested `trigger_conditions_attributes`. Mirrors the
31
+ * `trigger_type` → `condition_type` mapping that listTriggers uses for filtering.
32
+ * Returns undefined when there is no condition to build (no trigger_type), so
33
+ * callers can leave the field off the request entirely.
34
+ */
35
+ export declare function conditionAttributesFromLegacy(trigger_type: TriggerConditionType | undefined, configuration: Record<string, unknown> | undefined): TriggerConditionAttributes[] | undefined;
28
36
  /**
29
37
  * Interface for the Agent Orchestrator API client.
30
38
  * Used for dependency injection and testing.
@@ -256,6 +264,13 @@ export declare class AgentOrchestratorClient implements IAgentOrchestratorClient
256
264
  getTrigger(id: number): Promise<TriggerResponse>;
257
265
  createTrigger(data: CreateTriggerRequest): Promise<Trigger>;
258
266
  updateTrigger(id: number, data: UpdateTriggerRequest): Promise<Trigger>;
267
+ /**
268
+ * Builds the trigger_conditions_attributes for an update expressed with the
269
+ * ergonomic top-level `trigger_type` + `configuration` shape. Fetches the
270
+ * trigger to reuse the matching existing condition's id (so the condition is
271
+ * updated in place rather than duplicated).
272
+ */
273
+ private resolveUpdatedTriggerConditions;
259
274
  deleteTrigger(id: number): Promise<void>;
260
275
  toggleTrigger(id: number): Promise<Trigger>;
261
276
  getTriggerChannels(): Promise<TriggerChannelsResponse>;
@@ -3,6 +3,25 @@
3
3
  *
4
4
  * Used in integration tests to simulate API responses without hitting real endpoints.
5
5
  */
6
+ import { conditionAttributesFromLegacy } from './orchestrator-client.js';
7
+ /**
8
+ * Builds mock TriggerCondition rows from a create/update request, mirroring the
9
+ * real client: fold the ergonomic top-level trigger_type + configuration shape
10
+ * into nested condition attributes when the caller didn't supply them directly.
11
+ */
12
+ function buildMockTriggerConditions(data) {
13
+ const conditionAttributes = data.trigger_conditions_attributes ??
14
+ conditionAttributesFromLegacy(data.trigger_type, data.configuration) ??
15
+ [];
16
+ return conditionAttributes.map((c, i) => ({
17
+ id: i + 1,
18
+ condition_type: c.condition_type,
19
+ configuration: c.configuration,
20
+ description: `${c.condition_type} condition`,
21
+ last_triggered_at: null,
22
+ last_polled_at: null,
23
+ }));
24
+ }
6
25
  /**
7
26
  * Creates a mock Agent Orchestrator client for integration testing.
8
27
  */
@@ -751,14 +770,7 @@ export function createIntegrationMockOrchestratorClient(initialMockData) {
751
770
  return { trigger, recent_sessions: [] };
752
771
  },
753
772
  async createTrigger(data) {
754
- const conditions = (data.trigger_conditions_attributes ?? []).map((c, i) => ({
755
- id: i + 1,
756
- condition_type: c.condition_type,
757
- configuration: c.configuration,
758
- description: `${c.condition_type} condition`,
759
- last_triggered_at: null,
760
- last_polled_at: null,
761
- }));
773
+ const conditions = buildMockTriggerConditions(data);
762
774
  return {
763
775
  id: 1,
764
776
  name: data.name,
@@ -777,14 +789,7 @@ export function createIntegrationMockOrchestratorClient(initialMockData) {
777
789
  };
778
790
  },
779
791
  async updateTrigger(id, data) {
780
- const conditions = (data.trigger_conditions_attributes ?? []).map((c, i) => ({
781
- id: i + 1,
782
- condition_type: c.condition_type,
783
- configuration: c.configuration,
784
- description: `${c.condition_type} condition`,
785
- last_triggered_at: null,
786
- last_polled_at: null,
787
- }));
792
+ const conditions = buildMockTriggerConditions(data);
788
793
  return {
789
794
  id,
790
795
  name: data.name || 'Updated Trigger',
@@ -22,6 +22,19 @@ export function mapAgentRoot(raw) {
22
22
  default_model: raw.default_model,
23
23
  };
24
24
  }
25
+ /**
26
+ * Folds the ergonomic top-level `trigger_type` + `configuration` shape into the
27
+ * REST API's nested `trigger_conditions_attributes`. Mirrors the
28
+ * `trigger_type` → `condition_type` mapping that listTriggers uses for filtering.
29
+ * Returns undefined when there is no condition to build (no trigger_type), so
30
+ * callers can leave the field off the request entirely.
31
+ */
32
+ export function conditionAttributesFromLegacy(trigger_type, configuration) {
33
+ if (trigger_type === undefined) {
34
+ return undefined;
35
+ }
36
+ return [{ condition_type: trigger_type, configuration: configuration ?? {} }];
37
+ }
25
38
  /** Default timeout for API requests in milliseconds */
26
39
  const DEFAULT_TIMEOUT_MS = 30000;
27
40
  /**
@@ -387,13 +400,65 @@ export class AgentOrchestratorClient {
387
400
  return this.request('GET', `/triggers/${id}`);
388
401
  }
389
402
  async createTrigger(data) {
390
- const response = await this.request('POST', '/triggers', data);
403
+ const { trigger_type, configuration, trigger_conditions_attributes, ...rest } = data;
404
+ const body = { ...rest };
405
+ // The Rails v1 /triggers endpoint permits neither a top-level `trigger_type`
406
+ // nor a top-level `configuration`; the condition must be nested as
407
+ // `trigger_conditions_attributes: [{ condition_type:, configuration: }]`.
408
+ // An explicitly-supplied nested array (e.g. from wake_me_up_* tools) wins;
409
+ // otherwise fold the ergonomic top-level shape into a single condition.
410
+ const conditions = trigger_conditions_attributes ?? conditionAttributesFromLegacy(trigger_type, configuration);
411
+ if (conditions !== undefined) {
412
+ body.trigger_conditions_attributes = conditions;
413
+ }
414
+ const response = await this.request('POST', '/triggers', body);
391
415
  return response.trigger;
392
416
  }
393
417
  async updateTrigger(id, data) {
394
- const response = await this.request('PATCH', `/triggers/${id}`, data);
418
+ const { trigger_type, configuration, trigger_conditions_attributes, ...rest } = data;
419
+ const body = { ...rest };
420
+ if (trigger_conditions_attributes !== undefined) {
421
+ // Caller supplied the nested shape directly — forward verbatim.
422
+ body.trigger_conditions_attributes = trigger_conditions_attributes;
423
+ }
424
+ else if (trigger_type !== undefined || configuration !== undefined) {
425
+ // Ergonomic top-level shape. Resolve the existing condition's id so the
426
+ // condition is modified in place instead of a duplicate being appended
427
+ // (Rails uses accepts_nested_attributes_for). Metadata-only updates that
428
+ // omit both fields skip this entirely and never touch conditions.
429
+ body.trigger_conditions_attributes = await this.resolveUpdatedTriggerConditions(id, trigger_type, configuration);
430
+ }
431
+ const response = await this.request('PATCH', `/triggers/${id}`, body);
395
432
  return response.trigger;
396
433
  }
434
+ /**
435
+ * Builds the trigger_conditions_attributes for an update expressed with the
436
+ * ergonomic top-level `trigger_type` + `configuration` shape. Fetches the
437
+ * trigger to reuse the matching existing condition's id (so the condition is
438
+ * updated in place rather than duplicated).
439
+ */
440
+ async resolveUpdatedTriggerConditions(id, trigger_type, configuration) {
441
+ const { trigger } = await this.getTrigger(id);
442
+ const existing = trigger.conditions ?? [];
443
+ // Pick the condition to modify: the one matching the requested type, or the
444
+ // sole existing condition when no type was provided.
445
+ const target = trigger_type !== undefined
446
+ ? existing.find((c) => c.condition_type === trigger_type)
447
+ : existing.length === 1
448
+ ? existing[0]
449
+ : undefined;
450
+ const conditionType = trigger_type ?? target?.condition_type;
451
+ if (conditionType === undefined) {
452
+ throw new Error('Cannot update trigger configuration without a trigger_type when the trigger has zero or multiple conditions.');
453
+ }
454
+ return [
455
+ {
456
+ ...(target?.id !== undefined && { id: target.id }),
457
+ condition_type: conditionType,
458
+ configuration: configuration ?? target?.configuration ?? {},
459
+ },
460
+ ];
461
+ }
397
462
  async deleteTrigger(id) {
398
463
  await this.request('DELETE', `/triggers/${id}`);
399
464
  }
@@ -19,24 +19,24 @@ export declare const ActionTriggerSchema: z.ZodObject<{
19
19
  goal?: string | undefined;
20
20
  mcp_servers?: string[] | undefined;
21
21
  trigger_type?: "slack" | "schedule" | undefined;
22
+ configuration?: Record<string, unknown> | undefined;
22
23
  name?: string | undefined;
23
- id?: number | undefined;
24
24
  agent_root_name?: string | undefined;
25
25
  prompt_template?: string | undefined;
26
26
  reuse_session?: boolean | undefined;
27
- configuration?: Record<string, unknown> | undefined;
27
+ id?: number | undefined;
28
28
  }, {
29
29
  action: "create" | "update" | "delete" | "toggle";
30
30
  status?: "enabled" | "disabled" | undefined;
31
31
  goal?: string | undefined;
32
32
  mcp_servers?: string[] | undefined;
33
33
  trigger_type?: "slack" | "schedule" | undefined;
34
+ configuration?: Record<string, unknown> | undefined;
34
35
  name?: string | undefined;
35
- id?: number | undefined;
36
36
  agent_root_name?: string | undefined;
37
37
  prompt_template?: string | undefined;
38
38
  reuse_session?: boolean | undefined;
39
- configuration?: Record<string, unknown> | undefined;
39
+ id?: number | undefined;
40
40
  }>;
41
41
  export declare function actionTriggerTool(_server: Server, clientFactory: () => IAgentOrchestratorClient): {
42
42
  name: string;
@@ -11,16 +11,16 @@ export declare const ManageCategoriesSchema: z.ZodObject<{
11
11
  session_id: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
12
12
  }, "strip", z.ZodTypeAny, {
13
13
  action: "list" | "create" | "update" | "delete" | "reorder" | "set_session_category";
14
- description?: string | undefined;
15
14
  name?: string | undefined;
15
+ description?: string | undefined;
16
16
  session_id?: string | number | undefined;
17
17
  category_id?: number | null | undefined;
18
18
  is_frozen?: boolean | undefined;
19
19
  ids?: (number | "uncategorized")[] | undefined;
20
20
  }, {
21
21
  action: "list" | "create" | "update" | "delete" | "reorder" | "set_session_category";
22
- description?: string | undefined;
23
22
  name?: string | undefined;
23
+ description?: string | undefined;
24
24
  session_id?: string | number | undefined;
25
25
  category_id?: number | null | undefined;
26
26
  is_frozen?: boolean | undefined;
package/shared/types.d.ts CHANGED
@@ -298,6 +298,7 @@ export interface TriggerChannelsResponse {
298
298
  }>;
299
299
  }
300
300
  export interface TriggerConditionAttributes {
301
+ id?: number;
301
302
  condition_type: TriggerConditionType;
302
303
  configuration: Record<string, unknown>;
303
304
  }