openbot 0.3.6 → 0.4.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/README.md +15 -16
- package/dist/app/agent-ids.js +4 -0
- package/dist/app/cli.js +1 -1
- package/dist/app/config.js +0 -19
- package/dist/app/server.js +8 -14
- package/dist/bus/services.js +34 -124
- package/dist/harness/agent-invoke-run.js +44 -0
- package/dist/harness/agent-turn.js +99 -0
- package/dist/harness/channel-participants.js +40 -0
- package/dist/harness/constants.js +2 -0
- package/dist/harness/context-meter.js +97 -0
- package/dist/harness/context.js +95 -47
- package/dist/harness/dispatch.js +144 -0
- package/dist/harness/dispatcher.js +45 -156
- package/dist/harness/history.js +177 -0
- package/dist/harness/index.js +91 -0
- package/dist/harness/orchestration.js +88 -0
- package/dist/harness/participants.js +22 -0
- package/dist/harness/run-harness.js +154 -0
- package/dist/harness/run.js +98 -0
- package/dist/harness/runtime-factory.js +0 -34
- package/dist/harness/runtime.js +57 -0
- package/dist/harness/todo-dispatch.js +51 -0
- package/dist/harness/todos.js +5 -0
- package/dist/harness/turn.js +79 -0
- package/dist/plugins/approval/index.js +105 -149
- package/dist/plugins/delegation/index.js +119 -32
- package/dist/plugins/memory/index.js +103 -14
- package/dist/plugins/memory/service.js +152 -0
- package/dist/plugins/openbot/context.js +80 -0
- package/dist/plugins/openbot/history.js +98 -0
- package/dist/plugins/openbot/index.js +31 -0
- package/dist/plugins/openbot/runtime.js +317 -0
- package/dist/plugins/openbot/system-prompt.js +5 -0
- package/dist/plugins/plugin-manager/index.js +105 -0
- package/dist/plugins/storage/index.js +573 -0
- package/dist/plugins/storage/service.js +1159 -0
- package/dist/plugins/storage-tools/index.js +2 -2
- package/dist/plugins/thread-namer/index.js +72 -0
- package/dist/plugins/thread-naming/generate-title.js +44 -0
- package/dist/plugins/thread-naming/index.js +103 -0
- package/dist/plugins/threads/index.js +114 -0
- package/dist/plugins/todo/index.js +24 -25
- package/dist/plugins/ui/index.js +2 -32
- package/dist/registry/plugins.js +3 -9
- package/dist/services/plugins/domain.js +1 -0
- package/dist/services/plugins/plugin-cache.js +9 -0
- package/dist/services/plugins/registry.js +110 -0
- package/dist/services/plugins/service.js +177 -0
- package/dist/services/plugins/types.js +1 -0
- package/dist/services/process.js +29 -0
- package/dist/services/storage.js +11 -10
- package/dist/services/thread-naming.js +81 -0
- package/docs/agents.md +16 -10
- package/docs/architecture.md +2 -2
- package/docs/plugins.md +6 -15
- package/docs/templates/AGENT.example.md +7 -13
- package/package.json +1 -2
- package/src/app/agent-ids.ts +5 -0
- package/src/app/cli.ts +1 -1
- package/src/app/config.ts +1 -31
- package/src/app/server.ts +8 -16
- package/src/app/types.ts +63 -189
- package/src/harness/index.ts +145 -0
- package/src/plugins/approval/index.ts +91 -189
- package/src/plugins/delegation/index.ts +136 -39
- package/src/plugins/memory/index.ts +112 -15
- package/src/{services/memory.ts → plugins/memory/service.ts} +1 -1
- package/src/plugins/openbot/context.ts +91 -0
- package/src/plugins/openbot/history.ts +107 -0
- package/src/plugins/openbot/index.ts +37 -0
- package/src/plugins/openbot/runtime.ts +384 -0
- package/src/plugins/openbot/system-prompt.ts +7 -0
- package/src/plugins/plugin-manager/index.ts +122 -0
- package/src/plugins/shell/index.ts +1 -1
- package/src/plugins/storage/index.ts +633 -0
- package/src/{services/storage.ts → plugins/storage/service.ts} +224 -67
- package/src/{bus/types.ts → services/plugins/domain.ts} +16 -7
- package/src/services/plugins/plugin-cache.ts +13 -0
- package/src/{registry/plugins.ts → services/plugins/registry.ts} +25 -27
- package/src/services/{plugins.ts → plugins/service.ts} +96 -2
- package/src/{bus/plugin.ts → services/plugins/types.ts} +3 -3
- package/src/bus/services.ts +0 -954
- package/src/harness/context.ts +0 -365
- package/src/harness/dispatcher.ts +0 -379
- package/src/harness/mcp.ts +0 -78
- package/src/harness/runtime-factory.ts +0 -129
- package/src/harness/todo-advance.ts +0 -128
- package/src/plugins/ai-sdk/index.ts +0 -41
- package/src/plugins/ai-sdk/runtime.ts +0 -468
- package/src/plugins/ai-sdk/system-prompt.ts +0 -18
- package/src/plugins/mcp/index.ts +0 -128
- package/src/plugins/storage-tools/index.ts +0 -90
- package/src/plugins/todo/index.ts +0 -64
- package/src/plugins/ui/index.ts +0 -227
- /package/src/{harness → services}/process.ts +0 -0
package/src/app/types.ts
CHANGED
|
@@ -6,9 +6,9 @@ import {
|
|
|
6
6
|
PluginDescriptor,
|
|
7
7
|
Thread,
|
|
8
8
|
ThreadDetails,
|
|
9
|
-
} from '../
|
|
10
|
-
import type { PluginRef } from '../
|
|
11
|
-
import type { MemoryRecord } from '../
|
|
9
|
+
} from '../services/plugins/domain.js';
|
|
10
|
+
import type { PluginRef } from '../services/plugins/types.js';
|
|
11
|
+
import type { MemoryRecord } from '../plugins/memory/service.js';
|
|
12
12
|
|
|
13
13
|
export interface OpenBotState {
|
|
14
14
|
agentId: string;
|
|
@@ -19,15 +19,10 @@ export interface OpenBotState {
|
|
|
19
19
|
channelDetails?: ChannelDetails;
|
|
20
20
|
threadDetails?: ThreadDetails;
|
|
21
21
|
triggerEvent?: OpenBotEvent;
|
|
22
|
-
|
|
22
|
+
/** Active model string (e.g. `openai/gpt-4o-mini`). */
|
|
23
|
+
model?: string;
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
export type ShortTermMessage =
|
|
26
|
-
| { role: 'system'; content: string }
|
|
27
|
-
| { role: 'user'; content: string }
|
|
28
|
-
| { role: 'assistant'; content: string; toolCalls?: any[] }
|
|
29
|
-
| { role: 'tool'; content: string; toolCallId: string; toolName: string };
|
|
30
|
-
|
|
31
26
|
export type BaseEvent = {
|
|
32
27
|
id?: string;
|
|
33
28
|
type: string;
|
|
@@ -144,6 +139,7 @@ export type CreateAgentEvent = BaseEvent & {
|
|
|
144
139
|
name: string;
|
|
145
140
|
description?: string;
|
|
146
141
|
image?: string;
|
|
142
|
+
hidden?: boolean;
|
|
147
143
|
instructions: string;
|
|
148
144
|
plugins: PluginRef[];
|
|
149
145
|
};
|
|
@@ -164,6 +160,7 @@ export type UpdateAgentEvent = BaseEvent & {
|
|
|
164
160
|
name?: string;
|
|
165
161
|
description?: string;
|
|
166
162
|
image?: string;
|
|
163
|
+
hidden?: boolean;
|
|
167
164
|
instructions?: string;
|
|
168
165
|
plugins?: PluginRef[];
|
|
169
166
|
};
|
|
@@ -509,12 +506,26 @@ export type UIWidgetListItem = {
|
|
|
509
506
|
metadata?: Record<string, unknown>;
|
|
510
507
|
};
|
|
511
508
|
|
|
509
|
+
export type UIMediaItem = {
|
|
510
|
+
type: 'image' | 'video' | 'audio' | 'file';
|
|
511
|
+
url: string;
|
|
512
|
+
title?: string;
|
|
513
|
+
alt?: string;
|
|
514
|
+
thumbnailUrl?: string;
|
|
515
|
+
metadata?: Record<string, unknown>;
|
|
516
|
+
};
|
|
517
|
+
|
|
512
518
|
export type UIWidgetBase = {
|
|
513
519
|
widgetId: string;
|
|
514
520
|
title?: string;
|
|
515
521
|
description?: string;
|
|
516
|
-
|
|
522
|
+
/** Optional hero media for the widget */
|
|
523
|
+
media?: UIMediaItem;
|
|
524
|
+
/** Optional actions for the widget */
|
|
525
|
+
actions?: UIWidgetAction[];
|
|
517
526
|
state?: 'open' | 'submitted' | 'cancelled' | 'error';
|
|
527
|
+
display?: 'expanded' | 'collapsed';
|
|
528
|
+
size?: 'small' | 'medium' | 'large' | 'full';
|
|
518
529
|
metadata?: Record<string, unknown>;
|
|
519
530
|
};
|
|
520
531
|
|
|
@@ -543,19 +554,6 @@ export type UIListWidget = UIWidgetBase & {
|
|
|
543
554
|
|
|
544
555
|
export type UIWidgetSpec = UIMessageWidget | UIChoiceWidget | UIFormWidget | UIListWidget;
|
|
545
556
|
|
|
546
|
-
export type RenderUIWidgetData =
|
|
547
|
-
| (Omit<UIMessageWidget, 'widgetId'> & { widgetId?: string })
|
|
548
|
-
| (Omit<UIChoiceWidget, 'widgetId'> & { widgetId?: string })
|
|
549
|
-
| (Omit<UIFormWidget, 'widgetId'> & { widgetId?: string })
|
|
550
|
-
| (Omit<UIListWidget, 'widgetId'> & { widgetId?: string })
|
|
551
|
-
| {
|
|
552
|
-
kind: 'approval' | 'todo_list';
|
|
553
|
-
widgetId?: string;
|
|
554
|
-
title?: string;
|
|
555
|
-
props?: Record<string, unknown>;
|
|
556
|
-
metadata?: Record<string, unknown>;
|
|
557
|
-
};
|
|
558
|
-
|
|
559
557
|
export type UIWidgetEvent = BaseEvent & {
|
|
560
558
|
type: 'client:ui:widget';
|
|
561
559
|
data: UIWidgetSpec;
|
|
@@ -565,11 +563,6 @@ export type UIWidgetEvent = BaseEvent & {
|
|
|
565
563
|
};
|
|
566
564
|
};
|
|
567
565
|
|
|
568
|
-
export type RenderUIWidgetEvent = BaseEvent & {
|
|
569
|
-
type: 'action:render_ui_widget';
|
|
570
|
-
data: RenderUIWidgetData;
|
|
571
|
-
};
|
|
572
|
-
|
|
573
566
|
export type UIWidgetResponseEvent = BaseEvent & {
|
|
574
567
|
type: 'client:ui:widget:response';
|
|
575
568
|
data: {
|
|
@@ -580,80 +573,6 @@ export type UIWidgetResponseEvent = BaseEvent & {
|
|
|
580
573
|
};
|
|
581
574
|
};
|
|
582
575
|
|
|
583
|
-
export type HandoffEvent = BaseEvent & {
|
|
584
|
-
type: 'action:handoff';
|
|
585
|
-
data: {
|
|
586
|
-
agentId: string;
|
|
587
|
-
content: string;
|
|
588
|
-
};
|
|
589
|
-
meta?: {
|
|
590
|
-
toolCallId?: string;
|
|
591
|
-
[key: string]: any;
|
|
592
|
-
};
|
|
593
|
-
};
|
|
594
|
-
|
|
595
|
-
export type HandoffResultEvent = BaseEvent & {
|
|
596
|
-
type: 'action:handoff:result';
|
|
597
|
-
data: {
|
|
598
|
-
success: boolean;
|
|
599
|
-
agentId: string;
|
|
600
|
-
accepted: boolean;
|
|
601
|
-
};
|
|
602
|
-
meta: {
|
|
603
|
-
toolCallId: string;
|
|
604
|
-
agentId: string;
|
|
605
|
-
threadId?: string;
|
|
606
|
-
[key: string]: any;
|
|
607
|
-
};
|
|
608
|
-
};
|
|
609
|
-
|
|
610
|
-
/** Internal routing: handoff plugin → orchestrator only (not stored or broadcast). */
|
|
611
|
-
export type HandoffRequestEvent = BaseEvent & {
|
|
612
|
-
type: 'handoff:request';
|
|
613
|
-
data: {
|
|
614
|
-
agentId: string;
|
|
615
|
-
content: string;
|
|
616
|
-
};
|
|
617
|
-
meta?: Record<string, unknown>;
|
|
618
|
-
};
|
|
619
|
-
|
|
620
|
-
export type MCPListToolsEvent = BaseEvent & {
|
|
621
|
-
type: 'action:mcp_list_tools';
|
|
622
|
-
data: {
|
|
623
|
-
serverId: string;
|
|
624
|
-
};
|
|
625
|
-
};
|
|
626
|
-
|
|
627
|
-
export type MCPListToolsResultEvent = BaseEvent & {
|
|
628
|
-
type: 'action:mcp_list_tools:result';
|
|
629
|
-
data: {
|
|
630
|
-
success: boolean;
|
|
631
|
-
serverId: string;
|
|
632
|
-
tools: Array<{ name: string; description?: string; inputSchema?: unknown }>;
|
|
633
|
-
error?: string;
|
|
634
|
-
};
|
|
635
|
-
};
|
|
636
|
-
|
|
637
|
-
export type MCPCallEvent = BaseEvent & {
|
|
638
|
-
type: 'action:mcp_call';
|
|
639
|
-
data: {
|
|
640
|
-
serverId: string;
|
|
641
|
-
toolName: string;
|
|
642
|
-
args?: Record<string, unknown>;
|
|
643
|
-
};
|
|
644
|
-
};
|
|
645
|
-
|
|
646
|
-
export type MCPCallResultEvent = BaseEvent & {
|
|
647
|
-
type: 'action:mcp_call:result';
|
|
648
|
-
data: {
|
|
649
|
-
success: boolean;
|
|
650
|
-
serverId: string;
|
|
651
|
-
toolName: string;
|
|
652
|
-
result?: unknown;
|
|
653
|
-
error?: string;
|
|
654
|
-
};
|
|
655
|
-
};
|
|
656
|
-
|
|
657
576
|
export type ShellExecEvent = BaseEvent & {
|
|
658
577
|
type: 'action:shell_exec';
|
|
659
578
|
data: {
|
|
@@ -683,18 +602,6 @@ export type ShellExecResultEvent = BaseEvent & {
|
|
|
683
602
|
};
|
|
684
603
|
};
|
|
685
604
|
|
|
686
|
-
export type UserInputEvent = BaseEvent & {
|
|
687
|
-
type: 'user:input';
|
|
688
|
-
data: {
|
|
689
|
-
content: string;
|
|
690
|
-
};
|
|
691
|
-
meta?: {
|
|
692
|
-
userId?: string;
|
|
693
|
-
userName?: string;
|
|
694
|
-
userAvatarUrl?: string;
|
|
695
|
-
};
|
|
696
|
-
};
|
|
697
|
-
|
|
698
605
|
export type InstallPluginEvent = BaseEvent & {
|
|
699
606
|
type: 'action:plugin:install';
|
|
700
607
|
data: {
|
|
@@ -770,6 +677,25 @@ export type InstallAgentResultEvent = BaseEvent & {
|
|
|
770
677
|
|
|
771
678
|
export type MemoryScopeAlias = 'global' | 'agent' | 'channel';
|
|
772
679
|
|
|
680
|
+
export interface Usage {
|
|
681
|
+
promptTokens: number;
|
|
682
|
+
completionTokens: number;
|
|
683
|
+
totalTokens: number;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
export type AgentUsageEvent = BaseEvent & {
|
|
687
|
+
type: 'agent:usage';
|
|
688
|
+
data: {
|
|
689
|
+
usage: Usage;
|
|
690
|
+
model?: string;
|
|
691
|
+
};
|
|
692
|
+
meta: {
|
|
693
|
+
agentId: string;
|
|
694
|
+
threadId?: string;
|
|
695
|
+
runId?: string;
|
|
696
|
+
};
|
|
697
|
+
};
|
|
698
|
+
|
|
773
699
|
export type RememberEvent = BaseEvent & {
|
|
774
700
|
type: 'action:remember';
|
|
775
701
|
data: {
|
|
@@ -821,83 +747,41 @@ export type ForgetResultEvent = BaseEvent & {
|
|
|
821
747
|
};
|
|
822
748
|
};
|
|
823
749
|
|
|
824
|
-
export type
|
|
825
|
-
|
|
826
|
-
/**
|
|
827
|
-
* A single unit of work tracked in thread state. Todos are owned by the
|
|
828
|
-
* system (bus services); agents can only mutate them by calling the
|
|
829
|
-
* `todo_write` / `todo_update` tools so every change is observable on the
|
|
830
|
-
* event stream and audit-friendly.
|
|
831
|
-
*/
|
|
832
|
-
export interface TodoItem {
|
|
833
|
-
id: string;
|
|
834
|
-
content: string;
|
|
835
|
-
status: TodoStatus;
|
|
836
|
-
/** Optional agent id responsible for this item — drives autonomous handoffs. */
|
|
837
|
-
assignee?: string;
|
|
838
|
-
/** Agent id that created the todo (or "system"). */
|
|
839
|
-
createdBy: string;
|
|
840
|
-
createdAt: number;
|
|
841
|
-
updatedAt: number;
|
|
842
|
-
/**
|
|
843
|
-
* Captured final reply when this item reaches `done` (last `agent:output`
|
|
844
|
-
* from the assignee for that run). Lets downstream agents rely on thread
|
|
845
|
-
* state instead of merged short-term messages.
|
|
846
|
-
*/
|
|
847
|
-
result?: string;
|
|
848
|
-
}
|
|
849
|
-
|
|
850
|
-
export type TodoWriteInput = {
|
|
851
|
-
id?: string;
|
|
852
|
-
content: string;
|
|
853
|
-
status?: TodoStatus;
|
|
854
|
-
assignee?: string;
|
|
855
|
-
};
|
|
856
|
-
|
|
857
|
-
export type TodoWriteEvent = BaseEvent & {
|
|
858
|
-
type: 'action:todo_write';
|
|
750
|
+
export type DelegateTaskEvent = BaseEvent & {
|
|
751
|
+
type: 'action:delegate_task';
|
|
859
752
|
data: {
|
|
860
|
-
|
|
753
|
+
agentId: string;
|
|
754
|
+
prompt: string;
|
|
861
755
|
};
|
|
862
|
-
meta?: { toolCallId?: string; agentId?: string; threadId?: string };
|
|
863
756
|
};
|
|
864
757
|
|
|
865
|
-
export type
|
|
866
|
-
type: 'action:
|
|
758
|
+
export type DelegateTaskResultEvent = BaseEvent & {
|
|
759
|
+
type: 'action:delegate_task:result';
|
|
867
760
|
data: {
|
|
868
761
|
success: boolean;
|
|
869
|
-
|
|
762
|
+
output?: string;
|
|
870
763
|
error?: string;
|
|
871
764
|
};
|
|
872
|
-
meta?: { toolCallId?: string; agentId?: string; threadId?: string };
|
|
873
765
|
};
|
|
874
766
|
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
};
|
|
883
|
-
meta?: { toolCallId?: string; agentId?: string; threadId?: string };
|
|
884
|
-
};
|
|
767
|
+
/**
|
|
768
|
+
* Internal message representation to decouple harness history from specific AI SDKs.
|
|
769
|
+
*/
|
|
770
|
+
export type OpenBotMessage =
|
|
771
|
+
| { role: 'user'; content: string | OpenBotMessagePart[] }
|
|
772
|
+
| { role: 'assistant'; content: string | OpenBotMessagePart[] }
|
|
773
|
+
| { role: 'system'; content: string }
|
|
774
|
+
| { role: 'tool'; content: OpenBotMessagePart[] };
|
|
885
775
|
|
|
886
|
-
export type
|
|
887
|
-
type: '
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
todo?: TodoItem;
|
|
891
|
-
todos: TodoItem[];
|
|
892
|
-
error?: string;
|
|
893
|
-
};
|
|
894
|
-
meta?: { toolCallId?: string; agentId?: string; threadId?: string };
|
|
895
|
-
};
|
|
776
|
+
export type OpenBotMessagePart =
|
|
777
|
+
| { type: 'text'; text: string }
|
|
778
|
+
| { type: 'tool-call'; toolCallId: string; toolName: string; input: any }
|
|
779
|
+
| { type: 'tool-result'; toolCallId: string; toolName: string; output: any };
|
|
896
780
|
|
|
897
781
|
export type OpenBotEvent =
|
|
898
|
-
| UserInputEvent
|
|
899
782
|
| AgentInvokeEvent
|
|
900
783
|
| AgentOutputEvent
|
|
784
|
+
| AgentUsageEvent
|
|
901
785
|
| AgentRunStartEvent
|
|
902
786
|
| AgentRunEndEvent
|
|
903
787
|
| AgentRunStoppedEvent
|
|
@@ -952,15 +836,7 @@ export type OpenBotEvent =
|
|
|
952
836
|
| UpdateChannelEvent
|
|
953
837
|
| UpdateChannelResultEvent
|
|
954
838
|
| UIWidgetEvent
|
|
955
|
-
| RenderUIWidgetEvent
|
|
956
839
|
| UIWidgetResponseEvent
|
|
957
|
-
| HandoffEvent
|
|
958
|
-
| HandoffResultEvent
|
|
959
|
-
| HandoffRequestEvent
|
|
960
|
-
| MCPListToolsEvent
|
|
961
|
-
| MCPListToolsResultEvent
|
|
962
|
-
| MCPCallEvent
|
|
963
|
-
| MCPCallResultEvent
|
|
964
840
|
| ShellExecEvent
|
|
965
841
|
| ShellExecResultEvent
|
|
966
842
|
| InstallPluginEvent
|
|
@@ -977,7 +853,5 @@ export type OpenBotEvent =
|
|
|
977
853
|
| RecallResultEvent
|
|
978
854
|
| ForgetEvent
|
|
979
855
|
| ForgetResultEvent
|
|
980
|
-
|
|
|
981
|
-
|
|
|
982
|
-
| TodoUpdateEvent
|
|
983
|
-
| TodoUpdateResultEvent;
|
|
856
|
+
| DelegateTaskEvent
|
|
857
|
+
| DelegateTaskResultEvent;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { melony } from 'melony';
|
|
2
|
+
import { OpenBotEvent, OpenBotState } from '../app/types.js';
|
|
3
|
+
import { ensureEventId } from '../app/utils.js';
|
|
4
|
+
import { storageService } from '../plugins/storage/service.js';
|
|
5
|
+
import { STATE_AGENT_ID, ORCHESTRATOR_AGENT_ID } from '../app/agent-ids.js';
|
|
6
|
+
import { resolvePlugin } from '../services/plugins/registry.js';
|
|
7
|
+
import { ToolDefinition } from '../services/plugins/types.js';
|
|
8
|
+
|
|
9
|
+
export { STATE_AGENT_ID, ORCHESTRATOR_AGENT_ID };
|
|
10
|
+
|
|
11
|
+
export interface RunAgentOptions {
|
|
12
|
+
runId: string;
|
|
13
|
+
agentId: string;
|
|
14
|
+
event: OpenBotEvent;
|
|
15
|
+
channelId: string;
|
|
16
|
+
threadId?: string;
|
|
17
|
+
persistEvents?: boolean;
|
|
18
|
+
onEvent: (event: OpenBotEvent, state?: OpenBotState) => Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function emitEvent(
|
|
22
|
+
chunk: OpenBotEvent,
|
|
23
|
+
state: OpenBotState | undefined,
|
|
24
|
+
{
|
|
25
|
+
persistEvents,
|
|
26
|
+
channelId,
|
|
27
|
+
threadId,
|
|
28
|
+
onEvent,
|
|
29
|
+
parentAgentId,
|
|
30
|
+
parentToolCallId,
|
|
31
|
+
}: {
|
|
32
|
+
persistEvents: boolean;
|
|
33
|
+
channelId: string;
|
|
34
|
+
threadId?: string;
|
|
35
|
+
onEvent: RunAgentOptions['onEvent'];
|
|
36
|
+
parentAgentId?: string;
|
|
37
|
+
parentToolCallId?: string;
|
|
38
|
+
},
|
|
39
|
+
): Promise<void> {
|
|
40
|
+
ensureEventId(chunk);
|
|
41
|
+
|
|
42
|
+
// Enrich event with parent metadata if not already present
|
|
43
|
+
if (parentAgentId || parentToolCallId) {
|
|
44
|
+
chunk.meta = {
|
|
45
|
+
...chunk.meta,
|
|
46
|
+
parentAgentId: chunk.meta?.parentAgentId || parentAgentId,
|
|
47
|
+
parentToolCallId: chunk.meta?.parentToolCallId || parentToolCallId,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (persistEvents) {
|
|
52
|
+
await storageService.storeEvent({
|
|
53
|
+
channelId: state?.channelId || channelId,
|
|
54
|
+
threadId: state?.threadId || threadId,
|
|
55
|
+
event: chunk,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
await onEvent(chunk, state);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Runs a single agent turn.
|
|
64
|
+
* Fire and forget.
|
|
65
|
+
*/
|
|
66
|
+
export async function runAgent(options: RunAgentOptions): Promise<void> {
|
|
67
|
+
const { runId, agentId, event, channelId, threadId, onEvent } = options;
|
|
68
|
+
const persistEvents = options.persistEvents !== false;
|
|
69
|
+
|
|
70
|
+
const parentAgentId = event.meta?.parentAgentId;
|
|
71
|
+
const parentToolCallId = event.meta?.parentToolCallId;
|
|
72
|
+
|
|
73
|
+
const agentDetails = await storageService.getAgentDetails({ agentId });
|
|
74
|
+
|
|
75
|
+
const state = await storageService.getOpenBotState({
|
|
76
|
+
runId,
|
|
77
|
+
agentId,
|
|
78
|
+
channelId,
|
|
79
|
+
threadId,
|
|
80
|
+
event,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
await emitEvent(
|
|
84
|
+
{
|
|
85
|
+
type: 'agent:run:start',
|
|
86
|
+
data: { runId, agentId, channelId, threadId },
|
|
87
|
+
} as OpenBotEvent,
|
|
88
|
+
state,
|
|
89
|
+
{ persistEvents, channelId, threadId, onEvent, parentAgentId, parentToolCallId },
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
const pluginRefs = agentDetails.pluginRefs ?? [];
|
|
94
|
+
const tools: Record<string, ToolDefinition> = {};
|
|
95
|
+
|
|
96
|
+
for (const ref of pluginRefs) {
|
|
97
|
+
const plugin = await resolvePlugin(ref.id);
|
|
98
|
+
if (plugin?.toolDefinitions) {
|
|
99
|
+
Object.assign(tools, plugin.toolDefinitions);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const builder = melony<OpenBotState, OpenBotEvent>().initialState(state);
|
|
104
|
+
|
|
105
|
+
for (const ref of pluginRefs) {
|
|
106
|
+
const plugin = await resolvePlugin(ref.id);
|
|
107
|
+
if (!plugin) continue;
|
|
108
|
+
|
|
109
|
+
builder.use(
|
|
110
|
+
plugin.factory({
|
|
111
|
+
agentId,
|
|
112
|
+
agentDetails,
|
|
113
|
+
config: ref.config ?? {},
|
|
114
|
+
storage: storageService,
|
|
115
|
+
tools,
|
|
116
|
+
}),
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const runtime = builder.build();
|
|
121
|
+
const generator = runtime.run(event, { runId, state });
|
|
122
|
+
|
|
123
|
+
for await (const outputEvent of generator) {
|
|
124
|
+
await emitEvent(outputEvent, state, {
|
|
125
|
+
persistEvents,
|
|
126
|
+
channelId,
|
|
127
|
+
threadId,
|
|
128
|
+
onEvent,
|
|
129
|
+
parentAgentId,
|
|
130
|
+
parentToolCallId,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
} catch (error) {
|
|
134
|
+
console.error(`[harness] Error running agent ${agentId}:`, error);
|
|
135
|
+
} finally {
|
|
136
|
+
await emitEvent(
|
|
137
|
+
{
|
|
138
|
+
type: 'agent:run:end',
|
|
139
|
+
data: { runId, agentId, channelId, threadId },
|
|
140
|
+
} as OpenBotEvent,
|
|
141
|
+
state,
|
|
142
|
+
{ persistEvents, channelId, threadId, onEvent, parentAgentId, parentToolCallId },
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
}
|