@@ -91,12 +91,74 @@ func New(
9191 }
9292 adapter .SetController (controller , controllerInfo .Type , controllerInfo .UUID )
9393
94- emitResourceLoadDiagnostics (sessionID , runID , emit , "starting" , resourcePaths , nil )
95- if err := adapter .LoadResourcesWithProgress (resourcePaths , func (index int , total int , resolution mfw.ResourceBundleResolution , status string , err error ) {
96- emitResourceLoadDiagnostic (sessionID , runID , emit , index , total , resolution , status , err )
97- }); err != nil {
98- adapter .Destroy ()
99- return nil , fmt .Errorf ("加载资源失败: %w" , err )
94+ // 判断是否有启用的 agent,决定 Resource 的来源
95+ enabledAgents := filterEnabledAgents (req .Profile .Agents )
96+ usePoolResource := len (enabledAgents ) > 0 && agentPool != nil
97+
98+ if usePoolResource {
99+ // 通过 Pool 确保 agent 已绑定 Resource。
100+ // Pool 拥有 Resource 生命周期,agent 连接不会因 Runtime 销毁而断开。
101+ for _ , agent := range enabledAgents {
102+ prepared , prepErr := normalizeAgentProfile (agent )
103+ if prepErr != nil {
104+ continue
105+ }
106+ if _ , ensureErr := agentPool .EnsureBound (prepared , resourcePaths ); ensureErr != nil {
107+ if requiredAgent (prepared ) {
108+ adapter .Destroy ()
109+ return nil , fmt .Errorf ("agent EnsureBound 失败: %w" , ensureErr )
110+ }
111+ }
112+ }
113+ // 获取 Pool 的 Resource 供 Tasker 使用(与 agent 共享同一个 Resource)
114+ var poolResource * maa.Resource
115+ for _ , agent := range enabledAgents {
116+ prepared , prepErr := normalizeAgentProfile (agent )
117+ if prepErr != nil {
118+ continue
119+ }
120+ if r := agentPool .GetResource (prepared ); r != nil {
121+ poolResource = r
122+ break
123+ }
124+ }
125+ if poolResource == nil {
126+ adapter .Destroy ()
127+ return nil , fmt .Errorf ("agent pool resource 为空" )
128+ }
129+ adapter .SetBorrowedResource (poolResource )
130+
131+ // Connect agent(必须在 InitTasker 之前,确保 handlers 已注册到 Resource)
132+ for _ , agent := range enabledAgents {
133+ prepared , prepErr := normalizeAgentProfile (agent )
134+ if prepErr != nil {
135+ continue
136+ }
137+ client , _ := agentPool .Acquire (prepared )
138+ if client == nil {
139+ continue
140+ }
141+ if ! client .Connected () {
142+ if prepared .TimeoutMS > 0 {
143+ _ = client .SetTimeout (time .Duration (prepared .TimeoutMS ) * time .Millisecond )
144+ }
145+ if err := connectAgent (prepared , client ); err != nil {
146+ if requiredAgent (prepared ) {
147+ adapter .Destroy ()
148+ return nil , fmt .Errorf ("agent 连接失败: %w" , err )
149+ }
150+ }
151+ }
152+ }
153+ } else {
154+ // 无 agent 时,adapter 自己创建并拥有 Resource
155+ emitResourceLoadDiagnostics (sessionID , runID , emit , "starting" , resourcePaths , nil )
156+ if err := adapter .LoadResourcesWithProgress (resourcePaths , func (index int , total int , resolution mfw.ResourceBundleResolution , status string , err error ) {
157+ emitResourceLoadDiagnostic (sessionID , runID , emit , index , total , resolution , status , err )
158+ }); err != nil {
159+ adapter .Destroy ()
160+ return nil , fmt .Errorf ("加载资源失败: %w" , err )
161+ }
100162 }
101163
102164 overrideBundle , err := buildPipelineOverrideBundle (root , req )
@@ -144,9 +206,24 @@ func New(
144206 emit : emit ,
145207 }
146208
147- if err := r .connectAgents (req .Profile .Agents ); err != nil {
148- r .Destroy ()
149- return nil , err
209+ if usePoolResource {
210+ // agent 已在 InitTasker 之前连接,记录到 Runtime
211+ for _ , agent := range enabledAgents {
212+ prepared , prepErr := normalizeAgentProfile (agent )
213+ if prepErr != nil {
214+ continue
215+ }
216+ client , _ := agentPool .Acquire (prepared )
217+ if client != nil && client .Connected () && client .Alive () {
218+ r .agentClients = append (r .agentClients , client )
219+ r .emitAgentDiagnostic (prepared , "info" , "debug.agent.connected" , "agent 复用已有连接" , nil , nil )
220+ }
221+ }
222+ } else if len (req .Profile .Agents ) > 0 {
223+ if err := r .connectAgents (req .Profile .Agents ); err != nil {
224+ r .Destroy ()
225+ return nil , err
226+ }
150227 }
151228
152229 return r , nil
@@ -435,6 +512,8 @@ func (r *Runtime) Destroy() {
435512 r .mu .Lock ()
436513 defer r .mu .Unlock ()
437514
515+ // 不 Disconnect agent —— Pool 拥有连接生命周期,agent server 进程需要保持运行。
516+ // adapter 使用的是 Pool 的 Resource(borrowed),Destroy 时不会释放它。
438517 r .agentClients = nil
439518
440519 if r .adapter == nil {
@@ -539,6 +618,8 @@ func (r *Runtime) directModeOverride(mode protocol.RunMode) (map[string]interfac
539618}
540619
541620func (r * Runtime ) connectAgents (agents []protocol.AgentProfile ) error {
621+ resource := r .adapter .GetResource ()
622+
542623 for _ , agent := range agents {
543624 if ! agent .Enabled {
544625 continue
@@ -560,31 +641,45 @@ func (r *Runtime) connectAgents(agents []protocol.AgentProfile) error {
560641 r .emitAgentDiagnostic (prepared , "warning" , "debug.agent.create_failed" , err .Error (), nil , nil )
561642 continue
562643 }
563- alreadyConnected := client .Connected ()
564- if ! alreadyConnected && prepared .TimeoutMS > 0 {
565- if err := client .SetTimeout (time .Duration (prepared .TimeoutMS ) * time .Millisecond ); err != nil {
644+
645+ // 如果 agent 已连接(来自 Pool 复用),需要先断开再重连,
646+ // 因为 handlers 只在 Connect() 时注册到当时绑定的 Resource 上。
647+ if client .Connected () {
648+ _ = client .Disconnect ()
649+ }
650+
651+ // 绑定到 Runtime 的 Resource(Tasker 使用的同一个)
652+ if resource != nil {
653+ if err := client .BindResource (resource ); err != nil {
566654 if requiredAgent (prepared ) {
567655 return err
568656 }
569- r .emitAgentDiagnostic (prepared , "warning" , "debug.agent.timeout_failed " , err .Error (), nil , nil )
657+ r .emitAgentDiagnostic (prepared , "warning" , "debug.agent.bind_failed " , err .Error (), nil , nil )
570658 continue
571659 }
572660 }
573- if ! alreadyConnected {
574- if err := connectAgent (prepared , client ); err != nil {
661+
662+ if prepared .TimeoutMS > 0 {
663+ if err := client .SetTimeout (time .Duration (prepared .TimeoutMS ) * time .Millisecond ); err != nil {
575664 if requiredAgent (prepared ) {
576665 return err
577666 }
578- r .emitAgentDiagnostic (prepared , "warning" , "debug.agent.connect_failed " , err .Error (), nil , nil )
667+ r .emitAgentDiagnostic (prepared , "warning" , "debug.agent.timeout_failed " , err .Error (), nil , nil )
579668 continue
580669 }
581670 }
582- r .agentClients = append (r .agentClients , client )
583- message := "agent 已连接"
584- if alreadyConnected {
585- message = "agent 复用已有连接"
671+
672+ // Connect 会将 agent server 的 custom handlers 注册到当前绑定的 Resource 上
673+ if err := connectAgent (prepared , client ); err != nil {
674+ if requiredAgent (prepared ) {
675+ return err
676+ }
677+ r .emitAgentDiagnostic (prepared , "warning" , "debug.agent.connect_failed" , err .Error (), nil , nil )
678+ continue
586679 }
587- r .emitAgentDiagnostic (prepared , "info" , "debug.agent.connected" , message , nil , nil )
680+
681+ r .agentClients = append (r .agentClients , client )
682+ r .emitAgentDiagnostic (prepared , "info" , "debug.agent.connected" , "agent 已连接" , nil , nil )
588683 }
589684 return nil
590685}
@@ -619,18 +714,9 @@ func (r *Runtime) emitAgentDiagnostic(agent protocol.AgentProfile, severity stri
619714
620715func (r * Runtime ) acquireAgentClient (agent protocol.AgentProfile ) (* maa.AgentClient , error ) {
621716 if r .agentPool != nil {
622- return r .agentPool .EnsureBound (agent , r .resourcePaths )
623- }
624- client , err := createAgentClient (agent )
625- if err != nil {
626- return nil , err
627- }
628- if resource := r .adapter .GetResource (); resource != nil {
629- if err := client .BindResource (resource ); err != nil {
630- return nil , err
631- }
717+ return r .agentPool .Acquire (agent )
632718 }
633- return client , nil
719+ return createAgentClient ( agent )
634720}
635721
636722func (r * Runtime ) labelForRuntimeName (runtimeName string ) string {
@@ -851,6 +937,16 @@ func requiredAgent(agent protocol.AgentProfile) bool {
851937 return agent .Required == nil || * agent .Required
852938}
853939
940+ func filterEnabledAgents (agents []protocol.AgentProfile ) []protocol.AgentProfile {
941+ var enabled []protocol.AgentProfile
942+ for _ , agent := range agents {
943+ if agent .Enabled {
944+ enabled = append (enabled , agent )
945+ }
946+ }
947+ return enabled
948+ }
949+
854950func emitResourceLoadDiagnostics (sessionID string , runID string , emit events.EmitFunc , status string , paths []string , err error ) {
855951 if emit == nil {
856952 return
0 commit comments