@@ -78,11 +78,22 @@ def _filter_snapshot_to_specs(
7878 return CompositorSessionSnapshot (schema_version = snapshot .schema_version , layers = filtered_layers )
7979
8080
81- def _shell_layer_deps (* , include_drive : bool ) -> dict [str , str ]:
82- deps = {"execution_context" : DIFY_EXECUTION_CONTEXT_LAYER_ID }
83- if include_drive :
84- deps ["drive" ] = DIFY_DRIVE_LAYER_ID
85- return deps
81+ def _shell_layer_deps () -> dict [str , str ]:
82+ return {"execution_context" : DIFY_EXECUTION_CONTEXT_LAYER_ID }
83+
84+
85+ def _drive_layer_deps () -> dict [str , str ]:
86+ return {"shell" : DIFY_SHELL_LAYER_ID }
87+
88+
89+ def _shell_config_with_drive_ref (
90+ shell_config : DifyShellLayerConfig | None ,
91+ drive_config : DifyDriveLayerConfig | None ,
92+ ) -> DifyShellLayerConfig :
93+ config = shell_config or DifyShellLayerConfig ()
94+ if drive_config is None :
95+ return config
96+ return config .model_copy (update = {"agent_stub_drive_ref" : drive_config .drive_ref })
8697
8798
8899class AgentBackendModelConfig (BaseModel ):
@@ -263,14 +274,29 @@ def build_for_agent_app(self, run_input: AgentBackendAgentAppRunInput) -> Create
263274 ]
264275 )
265276
277+ include_shell = run_input .include_shell or run_input .drive_config is not None
278+ if include_shell :
279+ # Sandboxed bash workspace (dify.shell). It enters before drive so
280+ # drive can materialize mentioned targets with `dify-agent drive pull`
281+ # in the same shell-visible filesystem used by model commands.
282+ layers .append (
283+ RunLayerSpec (
284+ name = DIFY_SHELL_LAYER_ID ,
285+ type = DIFY_SHELL_LAYER_TYPE_ID ,
286+ deps = _shell_layer_deps (),
287+ metadata = run_input .metadata ,
288+ config = _shell_config_with_drive_ref (run_input .shell_config , run_input .drive_config ),
289+ )
290+ )
291+
266292 if run_input .drive_config is not None :
267- # Drive Skills & Files declaration (dify.drive): a config-only index;
268- # the agent pulls listed entries through the back proxy by drive_ref .
293+ # Drive Skills & Files declaration (dify.drive): the catalog plus
294+ # prompt-mentioned entries eagerly pulled through the shell layer .
269295 layers .append (
270296 RunLayerSpec (
271297 name = DIFY_DRIVE_LAYER_ID ,
272298 type = DIFY_DRIVE_LAYER_TYPE_ID ,
273- deps = { "execution_context" : DIFY_EXECUTION_CONTEXT_LAYER_ID } ,
299+ deps = _drive_layer_deps () ,
274300 metadata = run_input .metadata ,
275301 config = run_input .drive_config ,
276302 )
@@ -312,7 +338,7 @@ def build_for_agent_app(self, run_input: AgentBackendAgentAppRunInput) -> Create
312338 )
313339 )
314340
315- if run_input .knowledge is not None and run_input .knowledge .dataset_ids :
341+ if run_input .knowledge is not None and run_input .knowledge .sets :
316342 layers .append (
317343 RunLayerSpec (
318344 name = DIFY_KNOWLEDGE_BASE_LAYER_ID ,
@@ -336,21 +362,6 @@ def build_for_agent_app(self, run_input: AgentBackendAgentAppRunInput) -> Create
336362 )
337363 )
338364
339- if run_input .include_shell :
340- # Sandboxed bash workspace (dify.shell). Depends on execution_context
341- # so the agent server can mint per-command Agent Stub env, and on
342- # drive when present so that env points at /mnt/drive/<drive_ref>.
343- # shellctl connection itself is server-injected.
344- layers .append (
345- RunLayerSpec (
346- name = DIFY_SHELL_LAYER_ID ,
347- type = DIFY_SHELL_LAYER_TYPE_ID ,
348- deps = _shell_layer_deps (include_drive = run_input .drive_config is not None ),
349- metadata = run_input .metadata ,
350- config = run_input .shell_config or DifyShellLayerConfig (),
351- )
352- )
353-
354365 if run_input .output is not None :
355366 layers .append (
356367 RunLayerSpec (
@@ -445,7 +456,7 @@ def build_for_workflow_node(self, run_input: AgentBackendWorkflowNodeRunInput) -
445456 name = WORKFLOW_NODE_JOB_PROMPT_LAYER_ID ,
446457 type = PLAIN_PROMPT_LAYER_TYPE_ID ,
447458 metadata = {** run_input .metadata , "origin" : "workflow_node_job" },
448- config = PromptLayerConfig (prefix = run_input .workflow_node_job_prompt ),
459+ config = PromptLayerConfig (user = run_input .workflow_node_job_prompt ),
449460 ),
450461 RunLayerSpec (
451462 name = WORKFLOW_USER_PROMPT_LAYER_ID ,
@@ -462,14 +473,29 @@ def build_for_workflow_node(self, run_input: AgentBackendWorkflowNodeRunInput) -
462473 ]
463474 )
464475
476+ include_shell = run_input .include_shell or run_input .drive_config is not None
477+ if include_shell :
478+ # Sandboxed bash workspace (dify.shell). It enters before drive so
479+ # drive can materialize mentioned targets with `dify-agent drive pull`
480+ # in the same shell-visible filesystem used by model commands.
481+ layers .append (
482+ RunLayerSpec (
483+ name = DIFY_SHELL_LAYER_ID ,
484+ type = DIFY_SHELL_LAYER_TYPE_ID ,
485+ deps = _shell_layer_deps (),
486+ metadata = run_input .metadata ,
487+ config = _shell_config_with_drive_ref (run_input .shell_config , run_input .drive_config ),
488+ )
489+ )
490+
465491 if run_input .drive_config is not None :
466- # Drive Skills & Files declaration (dify.drive): a config-only index;
467- # the agent pulls listed entries through the back proxy by drive_ref .
492+ # Drive Skills & Files declaration (dify.drive): the catalog plus
493+ # prompt-mentioned entries eagerly pulled through the shell layer .
468494 layers .append (
469495 RunLayerSpec (
470496 name = DIFY_DRIVE_LAYER_ID ,
471497 type = DIFY_DRIVE_LAYER_TYPE_ID ,
472- deps = { "execution_context" : DIFY_EXECUTION_CONTEXT_LAYER_ID } ,
498+ deps = _drive_layer_deps () ,
473499 metadata = run_input .metadata ,
474500 config = run_input .drive_config ,
475501 )
@@ -513,7 +539,7 @@ def build_for_workflow_node(self, run_input: AgentBackendWorkflowNodeRunInput) -
513539 )
514540 )
515541
516- if run_input .knowledge is not None and run_input .knowledge .dataset_ids :
542+ if run_input .knowledge is not None and run_input .knowledge .sets :
517543 layers .append (
518544 RunLayerSpec (
519545 name = DIFY_KNOWLEDGE_BASE_LAYER_ID ,
@@ -537,21 +563,6 @@ def build_for_workflow_node(self, run_input: AgentBackendWorkflowNodeRunInput) -
537563 )
538564 )
539565
540- if run_input .include_shell :
541- # Sandboxed bash workspace (dify.shell). Depends on execution_context
542- # so the agent server can mint per-command Agent Stub env, and on
543- # drive when present so that env points at /mnt/drive/<drive_ref>.
544- # shellctl connection itself is server-injected.
545- layers .append (
546- RunLayerSpec (
547- name = DIFY_SHELL_LAYER_ID ,
548- type = DIFY_SHELL_LAYER_TYPE_ID ,
549- deps = _shell_layer_deps (include_drive = run_input .drive_config is not None ),
550- metadata = run_input .metadata ,
551- config = run_input .shell_config or DifyShellLayerConfig (),
552- )
553- )
554-
555566 if run_input .output is not None :
556567 layers .append (
557568 RunLayerSpec (
0 commit comments