diff --git a/api/controllers/console/app/agent.py b/api/controllers/console/app/agent.py
index 43896aa1eb7..fd725a75a1f 100644
--- a/api/controllers/console/app/agent.py
+++ b/api/controllers/console/app/agent.py
@@ -330,8 +330,7 @@ def _delete_skill_for_app(*, current_user: Account, app_model: App, slug: str, a
file_ref.drive_key
for skill in agent_soul.files.skills
if (
- skill.path
- or (AgentSoulFilesService.skill_path_from_key(skill.skill_md_key) if skill.skill_md_key else "")
+ skill.path or (AgentSoulFilesService.skill_path_from_key(skill.skill_md_key) if skill.skill_md_key else "")
).strip("/")
== slug
for file_ref in skill.file_refs
diff --git a/api/core/workflow/nodes/agent_v2/runtime_request_builder.py b/api/core/workflow/nodes/agent_v2/runtime_request_builder.py
index ff15ebfad5f..46a1edefcf3 100644
--- a/api/core/workflow/nodes/agent_v2/runtime_request_builder.py
+++ b/api/core/workflow/nodes/agent_v2/runtime_request_builder.py
@@ -674,9 +674,7 @@ def build_drive_aware_soul_mention_resolver(
base_resolver = build_soul_mention_resolver(agent_soul)
skill_names_by_key = {
- skill.skill_md_key: skill.name
- for skill in agent_soul.files.skills
- if skill.skill_md_key and skill.name
+ skill.skill_md_key: skill.name for skill in agent_soul.files.skills if skill.skill_md_key and skill.name
}
file_names_by_key = {
file_ref.drive_key: file_ref.name or file_ref.drive_key.rsplit("/", 1)[-1]
diff --git a/api/models/agent.py b/api/models/agent.py
index 2e10118ff61..e3d194a684b 100644
--- a/api/models/agent.py
+++ b/api/models/agent.py
@@ -240,9 +240,7 @@ class AgentConfigDraft(DefaultFieldsMixin, Base):
tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False)
agent_id: Mapped[str] = mapped_column(StringUUID, nullable=False)
- draft_type: Mapped[AgentConfigDraftType] = mapped_column(
- EnumText(AgentConfigDraftType, length=32), nullable=False
- )
+ draft_type: Mapped[AgentConfigDraftType] = mapped_column(EnumText(AgentConfigDraftType, length=32), nullable=False)
account_id: Mapped[str | None] = mapped_column(StringUUID, nullable=True)
draft_owner_key: Mapped[str] = mapped_column(String(255), nullable=False, default="")
base_snapshot_id: Mapped[str | None] = mapped_column(StringUUID, nullable=True)
diff --git a/api/openapi/markdown/console-openapi.md b/api/openapi/markdown/console-openapi.md
index 347b6ef33f4..4cb878d1be2 100644
--- a/api/openapi/markdown/console-openapi.md
+++ b/api/openapi/markdown/console-openapi.md
@@ -465,6 +465,83 @@ Check if activation token is valid
| ---- | ----------- |
| 204 | Agent service API key deleted |
+### [DELETE] /agent/{agent_id}/build-draft
+#### Parameters
+
+| Name | Located in | Description | Required | Schema |
+| ---- | ---------- | ----------- | -------- | ------ |
+| agent_id | path | | Yes | string (uuid) |
+
+#### Responses
+
+| Code | Description | Schema |
+| ---- | ----------- | ------ |
+| 200 | Agent build draft discarded | **application/json**: [AgentSimpleResultResponse](#agentsimpleresultresponse)
|
+
+### [GET] /agent/{agent_id}/build-draft
+#### Parameters
+
+| Name | Located in | Description | Required | Schema |
+| ---- | ---------- | ----------- | -------- | ------ |
+| agent_id | path | | Yes | string (uuid) |
+
+#### Responses
+
+| Code | Description | Schema |
+| ---- | ----------- | ------ |
+| 200 | Agent build draft | **application/json**: [AgentBuildDraftResponse](#agentbuilddraftresponse)
|
+
+### [PUT] /agent/{agent_id}/build-draft
+#### Parameters
+
+| Name | Located in | Description | Required | Schema |
+| ---- | ---------- | ----------- | -------- | ------ |
+| agent_id | path | | Yes | string (uuid) |
+
+#### Request Body
+
+| Required | Schema |
+| -------- | ------ |
+| Yes | **application/json**: [ComposerSavePayload](#composersavepayload)
|
+
+#### Responses
+
+| Code | Description | Schema |
+| ---- | ----------- | ------ |
+| 200 | Agent build draft saved | **application/json**: [AgentBuildDraftResponse](#agentbuilddraftresponse)
|
+
+### [POST] /agent/{agent_id}/build-draft/apply
+#### Parameters
+
+| Name | Located in | Description | Required | Schema |
+| ---- | ---------- | ----------- | -------- | ------ |
+| agent_id | path | | Yes | string (uuid) |
+
+#### Responses
+
+| Code | Description | Schema |
+| ---- | ----------- | ------ |
+| 200 | Agent build draft applied | **application/json**: [AgentBuildDraftApplyResponse](#agentbuilddraftapplyresponse)
|
+
+### [POST] /agent/{agent_id}/build-draft/checkout
+#### Parameters
+
+| Name | Located in | Description | Required | Schema |
+| ---- | ---------- | ----------- | -------- | ------ |
+| agent_id | path | | Yes | string (uuid) |
+
+#### Request Body
+
+| Required | Schema |
+| -------- | ------ |
+| Yes | **application/json**: [AgentBuildDraftCheckoutPayload](#agentbuilddraftcheckoutpayload)
|
+
+#### Responses
+
+| Code | Description | Schema |
+| ---- | ----------- | ------ |
+| 200 | Agent build draft checked out | **application/json**: [AgentBuildDraftResponse](#agentbuilddraftresponse)
|
+
### [GET] /agent/{agent_id}/chat-messages
Get Agent App chat messages for a conversation with pagination
@@ -856,6 +933,26 @@ Get Agent App message details by ID
| 200 | Message retrieved successfully | **application/json**: [MessageDetailResponse](#messagedetailresponse)
|
| 404 | Agent or message not found | |
+### [POST] /agent/{agent_id}/publish
+#### Parameters
+
+| Name | Located in | Description | Required | Schema |
+| ---- | ---------- | ----------- | -------- | ------ |
+| agent_id | path | | Yes | string (uuid) |
+
+#### Request Body
+
+| Required | Schema |
+| -------- | ------ |
+| Yes | **application/json**: [AgentPublishPayload](#agentpublishpayload)
|
+
+#### Responses
+
+| Code | Description | Schema |
+| ---- | ----------- | ------ |
+| 200 | Agent draft published | **application/json**: [AgentPublishResponse](#agentpublishresponse)
|
+| 403 | Insufficient permissions | |
+
### [GET] /agent/{agent_id}/referencing-workflows
List workflow apps that reference this Agent App's bound Agent (read-only)
@@ -12170,9 +12267,10 @@ Default namespace
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
-| active_config_snapshot | [AgentConfigSnapshotSummaryResponse](#agentconfigsnapshotsummaryresponse) | | Yes |
+| active_config_snapshot | [AgentConfigSnapshotSummaryResponse](#agentconfigsnapshotsummaryresponse) | | No |
| agent | [AgentComposerAgentResponse](#agentcomposeragentresponse) | | Yes |
| agent_soul | [AgentSoulConfig](#agentsoulconfig) | | Yes |
+| draft | [AgentConfigDraftSummaryResponse](#agentconfigdraftsummaryresponse) | | No |
| save_options | [ [ComposerSaveStrategy](#composersavestrategy) ] | | Yes |
| validation | [ComposerValidationFindingsResponse](#composervalidationfindingsresponse) | | No |
| variant | string | | Yes |
@@ -12227,7 +12325,7 @@ Default namespace
| name | string | | Yes |
| permission_keys | [ string ] | | No |
| role | string | | No |
-| site | [Site](#site) | | No |
+| site | [AppDetailSiteResponse](#appdetailsiteresponse) | | No |
| tags | [ [Tag](#tag) ] | | No |
| tracing | [JSONValue](#jsonvalue) | | No |
| updated_at | integer | | No |
@@ -12335,6 +12433,27 @@ default (the config form sends the full desired feature state on save).
| date | string | | Yes |
| interactions | number | | Yes |
+#### AgentBuildDraftApplyResponse
+
+| Name | Type | Description | Required |
+| ---- | ---- | ----------- | -------- |
+| draft | object | | Yes |
+| result | string | | Yes |
+
+#### AgentBuildDraftCheckoutPayload
+
+| Name | Type | Description | Required |
+| ---- | ---- | ----------- | -------- |
+| force | boolean | Overwrite the existing current-user build draft | No |
+
+#### AgentBuildDraftResponse
+
+| Name | Type | Description | Required |
+| ---- | ---- | ----------- | -------- |
+| agent_soul | object | | Yes |
+| draft | object | | Yes |
+| variant | string | | Yes |
+
#### AgentCliToolAuthorizationStatus
Authorization state for Agent-scoped CLI tools.
@@ -12398,8 +12517,12 @@ Risk marker for CLI tool bootstrap commands.
| ---- | ---- | ----------- | -------- |
| active_config_snapshot_id | string | | No |
| description | string | | Yes |
+| icon | string | | No |
+| icon_background | string | | No |
+| icon_type | string | | No |
| id | string | | Yes |
| name | string | | Yes |
+| role | string | | No |
| scope | [AgentScope](#agentscope) | | Yes |
| status | [AgentStatus](#agentstatus) | | Yes |
@@ -12486,8 +12609,10 @@ Risk marker for CLI tool bootstrap commands.
| ---- | ---- | ----------- | -------- |
| cli_tools | [ [AgentCliToolConfig](#agentclitoolconfig) ] | | No |
| dify_tools | [ [AgentComposerDifyToolCandidateResponse](#agentcomposerdifytoolcandidateresponse) ] | | No |
+| files | [ [AgentFileRefConfig](#agentfilerefconfig) ] | | No |
| human_contacts | [ [AgentHumanContactConfig](#agenthumancontactconfig) ] | | No |
| knowledge_sets | [ [AgentComposerKnowledgeSetCandidateResponse](#agentcomposerknowledgesetcandidateresponse) ] | | No |
+| skills | [ [AgentSkillRefConfig](#agentskillrefconfig) ] | | No |
#### AgentComposerSoulLockResponse
@@ -12506,6 +12631,28 @@ Risk marker for CLI tool bootstrap commands.
| result | string | | Yes |
| warnings | [ [ComposerValidationWarningResponse](#composervalidationwarningresponse) ] | | No |
+#### AgentConfigDraftSummaryResponse
+
+| Name | Type | Description | Required |
+| ---- | ---- | ----------- | -------- |
+| account_id | string | | No |
+| agent_id | string | | Yes |
+| base_snapshot_id | string | | No |
+| created_at | integer | | No |
+| created_by | string | | No |
+| draft_type | [AgentConfigDraftType](#agentconfigdrafttype) | | Yes |
+| id | string | | Yes |
+| updated_at | integer | | No |
+| updated_by | string | | No |
+
+#### AgentConfigDraftType
+
+Editable Agent Soul draft workspace type.
+
+| Name | Type | Description | Required |
+| ---- | ---- | ----------- | -------- |
+| AgentConfigDraftType | string | Editable Agent Soul draft workspace type. | |
+
#### AgentConfigRevisionOperation
Audit operation recorded for Agent Soul version/revision changes.
@@ -12555,6 +12702,8 @@ Audit operation recorded for Agent Soul version/revision changes.
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| active_config_snapshot_id | string | | Yes |
+| draft_config_id | string | | No |
+| restored_version_id | string | | No |
| result | string | | Yes |
#### AgentConfigSnapshotSummaryResponse
@@ -12898,6 +13047,12 @@ the current roster/workflow APIs scoped to Dify Agent.
#### AgentKnowledgeMetadataFilteringConfig
+Per-set metadata filtering policy.
+
+The Python attribute uses ``metadata_model_config`` for clarity because the
+model belongs to metadata filtering specifically, while the external API and
+generated schema keep the historical ``model_config`` field name via alias.
+
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| conditions | [AgentKnowledgeMetadataConditions](#agentknowledgemetadataconditions) | | No |
@@ -12915,6 +13070,13 @@ the current roster/workflow APIs scoped to Dify Agent.
#### AgentKnowledgeQueryConfig
+Per-set query policy for Agent v2 knowledge retrieval.
+
+Agent v2 stores knowledge as explicit ``knowledge.sets`` rather than the
+legacy flat ``datasets`` / ``query_mode`` / ``query_config`` shape. Each
+set owns its own query policy, so ``user_query`` must carry an explicit
+``value`` while ``generated_query`` leaves that value empty.
+
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| mode | [AgentKnowledgeQueryMode](#agentknowledgequerymode) | | Yes |
@@ -12935,6 +13097,12 @@ the current roster/workflow APIs scoped to Dify Agent.
#### AgentKnowledgeRetrievalConfig
+Per-set retrieval policy for Agent v2 knowledge retrieval.
+
+Retrieval settings now live on each knowledge set instead of one shared
+flat config. A set may use either ``multiple`` retrieval with ``top_k`` or
+``single`` retrieval with a required model config.
+
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| mode | string,
**Available values:** "multiple", "single" | *Enum:* `"multiple"`, `"single"` | Yes |
@@ -12948,6 +13116,13 @@ the current roster/workflow APIs scoped to Dify Agent.
#### AgentKnowledgeSetConfig
+One explicit knowledge set in Agent v2.
+
+``knowledge.sets`` replaces the old flat knowledge config. Each set owns
+its datasets plus query, retrieval, and metadata policies. An individual
+set must contain at least one dataset id even though the overall knowledge
+section may be empty, which is how callers express "no knowledge layer".
+
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| datasets | [ [AgentKnowledgeDatasetConfig](#agentknowledgedatasetconfig) ] | | Yes |
@@ -13149,6 +13324,21 @@ the current roster/workflow APIs scoped to Dify Agent.
| ---- | ---- | ----------- | -------- |
| AgentProviderResponse | object | | |
+#### AgentPublishPayload
+
+| Name | Type | Description | Required |
+| ---- | ---- | ----------- | -------- |
+| version_note | string | Optional note for this published Agent version | No |
+
+#### AgentPublishResponse
+
+| Name | Type | Description | Required |
+| ---- | ---- | ----------- | -------- |
+| active_config_snapshot | object | | No |
+| active_config_snapshot_id | string | | Yes |
+| draft | object | | No |
+| result | string | | Yes |
+
#### AgentPublishedReferenceResponse
| Name | Type | Description | Required |
@@ -13276,6 +13466,28 @@ Visibility and lifecycle scope of an Agent record.
| enabled | boolean | | No |
| type | string | | No |
+#### AgentSimpleResultResponse
+
+| Name | Type | Description | Required |
+| ---- | ---- | ----------- | -------- |
+| result | string | | Yes |
+
+#### AgentSkillRefConfig
+
+| Name | Type | Description | Required |
+| ---- | ---- | ----------- | -------- |
+| description | string | | No |
+| file_id | string | | No |
+| file_refs | [ [AgentFileRefConfig](#agentfilerefconfig) ] | | No |
+| full_archive_file_id | string | | No |
+| full_archive_key | string | | No |
+| id | string | | No |
+| manifest_files | [ string ] | | No |
+| name | string | | No |
+| path | string | | No |
+| skill_md_file_id | string | | No |
+| skill_md_key | string | | No |
+
#### AgentSkillUploadResponse
| Name | Type | Description | Required |
@@ -13302,6 +13514,7 @@ Visibility and lifecycle scope of an Agent record.
| app_features | [AgentSoulAppFeaturesConfig](#agentsoulappfeaturesconfig) | | No |
| app_variables | [ [AppVariableConfig](#appvariableconfig) ] | | No |
| env | [AgentSoulEnvConfig](#agentsoulenvconfig) | | No |
+| files | [AgentSoulFilesConfig](#agentsoulfilesconfig) | | No |
| human | [AgentSoulHumanConfig](#agentsoulhumanconfig) | | No |
| knowledge | [AgentSoulKnowledgeConfig](#agentsoulknowledgeconfig) | | No |
| memory | [AgentSoulMemoryConfig](#agentsoulmemoryconfig) | | No |
@@ -13356,6 +13569,19 @@ old Agent tool payloads can be read while new payloads stay explicit.
| secret_refs | [ [AgentSecretRefConfig](#agentsecretrefconfig) ] | | No |
| variables | [ [AgentEnvVariableConfig](#agentenvvariableconfig) ] | | No |
+#### AgentSoulFilesConfig
+
+Versioned Agent Soul references to drive-backed skills and files.
+
+File bytes and drive value pointers stay in ``agent_drive_files``. This
+section records which drive keys belong to one Agent Soul snapshot so version
+restore/copy/runtime use the same skills/files view the user published.
+
+| Name | Type | Description | Required |
+| ---- | ---- | ----------- | -------- |
+| files | [ [AgentFileRefConfig](#agentfilerefconfig) ] | | No |
+| skills | [ [AgentSkillRefConfig](#agentskillrefconfig) ] | | No |
+
#### AgentSoulHumanConfig
| Name | Type | Description | Required |
@@ -13365,6 +13591,14 @@ old Agent tool payloads can be read while new payloads stay explicit.
#### AgentSoulKnowledgeConfig
+Top-level Agent v2 knowledge config.
+
+Agent v2 models knowledge as explicit sets instead of one flat
+``datasets`` / ``query_mode`` / ``query_config`` block. An empty ``sets``
+list means no knowledge layer should be emitted at runtime, while set-name
+uniqueness stays case-insensitive because runtime selection addresses sets
+by name.
+
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| sets | [ [AgentKnowledgeSetConfig](#agentknowledgesetconfig) ] | | No |
@@ -13841,6 +14075,35 @@ Enum class for api provider schema type.
| use_icon_as_answer_icon | boolean | | No |
| workflow | [WorkflowPartial](#workflowpartial) | | No |
+#### AppDetailSiteResponse
+
+| Name | Type | Description | Required |
+| ---- | ---- | ----------- | -------- |
+| access_token | string | | No |
+| app_base_url | string | | No |
+| chat_color_theme | string | | No |
+| chat_color_theme_inverted | boolean | | No |
+| code | string | | No |
+| copyright | string | | No |
+| created_at | integer | | No |
+| created_by | string | | No |
+| custom_disclaimer | string | | No |
+| customize_domain | string | | No |
+| customize_token_strategy | string | | No |
+| default_language | string | | No |
+| description | string | | No |
+| icon | string | | No |
+| icon_background | string | | No |
+| icon_type | string
[IconType](#icontype) | | No |
+| icon_url | string | | Yes |
+| privacy_policy | string | | No |
+| prompt_public | boolean | | No |
+| show_workflow_steps | boolean | | No |
+| title | string | | No |
+| updated_at | integer | | No |
+| updated_by | string | | No |
+| use_icon_as_answer_icon | boolean | | No |
+
#### AppDetailWithSite
| Name | Type | Description | Required |
@@ -13866,7 +14129,7 @@ Enum class for api provider schema type.
| model_config | [ModelConfig](#modelconfig) | | No |
| name | string | | Yes |
| permission_keys | [ string ] | | No |
-| site | [Site](#site) | | No |
+| site | [AppDetailSiteResponse](#appdetailsiteresponse) | | No |
| tags | [ [Tag](#tag) ] | | No |
| tracing | [JSONValue](#jsonvalue) | | No |
| updated_at | integer | | No |
@@ -14270,6 +14533,7 @@ Button styles for user actions.
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| conversation_id | string | Conversation ID | No |
+| draft_type | string,
**Available values:** "debug_build", "draft",
**Default:** draft | Agent App debug config source. Use debug_build while the Agent is in build mode.
*Enum:* `"debug_build"`, `"draft"` | No |
| files | [ object ] | Uploaded files | No |
| inputs | object | | Yes |
| model_config | object | | No |
diff --git a/api/services/agent/soul_files_service.py b/api/services/agent/soul_files_service.py
index 34c787386fc..3f63ce078a3 100644
--- a/api/services/agent/soul_files_service.py
+++ b/api/services/agent/soul_files_service.py
@@ -287,11 +287,7 @@ class AgentSoulFilesService:
manifest_files=metadata.manifest_files,
)
existing_ref = next(
- (
- existing
- for existing in agent_soul.files.skills
- if existing.skill_md_key == key or existing.path == path
- ),
+ (existing for existing in agent_soul.files.skills if existing.skill_md_key == key or existing.path == path),
None,
)
file_refs = list(existing_ref.file_refs) if existing_ref else []
@@ -303,9 +299,7 @@ class AgentSoulFilesService:
ref.full_archive_file_id = archive_ref.file_id
ref.file_refs = sorted(file_refs, key=lambda value: value.drive_key or value.name)
skills = [
- existing
- for existing in agent_soul.files.skills
- if existing.skill_md_key != key and existing.path != path
+ existing for existing in agent_soul.files.skills if existing.skill_md_key != key and existing.path != path
]
skills.append(ref)
skills.sort(key=lambda value: value.path or value.skill_md_key or "")
diff --git a/api/services/agent/workflow_publish_service.py b/api/services/agent/workflow_publish_service.py
index 1cc5d63eef3..8b6f76d8b10 100644
--- a/api/services/agent/workflow_publish_service.py
+++ b/api/services/agent/workflow_publish_service.py
@@ -285,9 +285,8 @@ class WorkflowAgentPublishService:
continue
if not isinstance(binding_payload, Mapping):
raise ValueError(f"Workflow Agent node {node_id} has invalid agent_binding.")
- if (
- binding_payload.get("binding_type") == WorkflowAgentBindingType.INLINE_AGENT.value
- and (not binding_payload.get("agent_id") or not binding_payload.get("current_snapshot_id"))
+ if binding_payload.get("binding_type") == WorkflowAgentBindingType.INLINE_AGENT.value and (
+ not binding_payload.get("agent_id") or not binding_payload.get("current_snapshot_id")
):
continue
cls._sync_agent_binding_for_node(
diff --git a/api/services/agent_drive_service.py b/api/services/agent_drive_service.py
index 0009fb8845c..d7888288363 100644
--- a/api/services/agent_drive_service.py
+++ b/api/services/agent_drive_service.py
@@ -891,9 +891,7 @@ class AgentDriveService:
file_id: str,
) -> str:
if file_kind == AgentDriveFileKind.TOOL_FILE:
- tool_file = session.scalar(
- select(ToolFile).where(ToolFile.id == file_id, ToolFile.tenant_id == tenant_id)
- )
+ tool_file = session.scalar(select(ToolFile).where(ToolFile.id == file_id, ToolFile.tenant_id == tenant_id))
if tool_file is None:
raise AgentDriveError("drive_key_not_found", "drive value record is missing", status_code=404)
return tool_file.file_key
diff --git a/api/tests/unit_tests/core/workflow/nodes/agent_v2/test_runtime_request_builder.py b/api/tests/unit_tests/core/workflow/nodes/agent_v2/test_runtime_request_builder.py
index a627481c378..9740a26db0f 100644
--- a/api/tests/unit_tests/core/workflow/nodes/agent_v2/test_runtime_request_builder.py
+++ b/api/tests/unit_tests/core/workflow/nodes/agent_v2/test_runtime_request_builder.py
@@ -599,9 +599,7 @@ def test_build_maps_agent_soul_knowledge_to_knowledge_layer_config():
"metadata_model_config": None,
"conditions": {
"logical_operator": "and",
- "conditions": [
- {"name": "category", "comparison_operator": "contains", "value": "auth"}
- ],
+ "conditions": [{"name": "category", "comparison_operator": "contains", "value": "auth"}],
},
},
},
diff --git a/api/tests/unit_tests/services/agent/test_agent_services.py b/api/tests/unit_tests/services/agent/test_agent_services.py
index badaa766b25..337d742fe9f 100644
--- a/api/tests/unit_tests/services/agent/test_agent_services.py
+++ b/api/tests/unit_tests/services/agent/test_agent_services.py
@@ -1756,9 +1756,7 @@ def test_active_config_is_published_flags_handle_matching_and_empty_snapshots():
base_snapshot_id="version-1",
config_snapshot=AgentSoulConfig(),
)
- service = AgentRosterService(
- FakeSession(scalars=[["agent-1"], [published_draft], ["agent-1"], [published_draft]])
- )
+ service = AgentRosterService(FakeSession(scalars=[["agent-1"], [published_draft], ["agent-1"], [published_draft]]))
flags = service.load_active_config_is_published_by_agent_id(tenant_id="tenant-1", agents=[agent, draft_agent])
@@ -1784,10 +1782,13 @@ def test_active_config_is_published_skips_empty_agent_ids():
)
fake_session = FakeSession(scalars=[["should-not-be-read"]])
- assert AgentRosterService(fake_session).load_active_config_is_published_by_agent_id(
- tenant_id="tenant-1",
- agents=[empty_id_agent],
- ) == {}
+ assert (
+ AgentRosterService(fake_session).load_active_config_is_published_by_agent_id(
+ tenant_id="tenant-1",
+ agents=[empty_id_agent],
+ )
+ == {}
+ )
assert fake_session._scalars == [["should-not-be-read"]]
diff --git a/api/tests/unit_tests/services/agent/test_agent_soul_files_service.py b/api/tests/unit_tests/services/agent/test_agent_soul_files_service.py
index 569d2357e38..57bd25e9a0d 100644
--- a/api/tests/unit_tests/services/agent/test_agent_soul_files_service.py
+++ b/api/tests/unit_tests/services/agent/test_agent_soul_files_service.py
@@ -146,9 +146,7 @@ def test_apply_drive_commit_removes_refs_without_touching_unrelated_entries():
)
AgentSoulFilesService._apply_commit_item(agent_soul=soul, item={"key": "files/sample.pdf", "removed": True})
- AgentSoulFilesService._apply_commit_item(
- agent_soul=soul, item={"key": "tender-analyzer/SKILL.md", "removed": True}
- )
+ AgentSoulFilesService._apply_commit_item(agent_soul=soul, item={"key": "tender-analyzer/SKILL.md", "removed": True})
assert [file_ref.drive_key for file_ref in soul.files.files] == ["files/keep.pdf"]
assert soul.files.skills == []
diff --git a/eslint-suppressions.json b/eslint-suppressions.json
index f9559a3e71f..07ee471532b 100644
--- a/eslint-suppressions.json
+++ b/eslint-suppressions.json
@@ -878,14 +878,6 @@
"count": 1
}
},
- "web/app/components/app/overview/settings/index.tsx": {
- "jsx-a11y/click-events-have-key-events": {
- "count": 1
- },
- "jsx-a11y/no-static-element-interactions": {
- "count": 1
- }
- },
"web/app/components/app/overview/workflow-hidden-input-fields.tsx": {
"no-restricted-imports": {
"count": 1
@@ -1198,14 +1190,6 @@
"count": 1
}
},
- "web/app/components/base/chat/chat/chat-input-area/index.tsx": {
- "jsx-a11y/no-autofocus": {
- "count": 1
- },
- "ts/no-explicit-any": {
- "count": 3
- }
- },
"web/app/components/base/chat/chat/check-input-forms-hooks.ts": {
"ts/no-explicit-any": {
"count": 1
@@ -1236,14 +1220,6 @@
"count": 17
}
},
- "web/app/components/base/chat/chat/index.tsx": {
- "ts/no-explicit-any": {
- "count": 2
- },
- "ts/no-non-null-asserted-optional-chain": {
- "count": 1
- }
- },
"web/app/components/base/chat/chat/log/index.tsx": {
"jsx-a11y/click-events-have-key-events": {
"count": 1
@@ -4554,9 +4530,6 @@
"web/app/components/workflow-app/hooks/use-nodes-sync-draft.ts": {
"no-restricted-imports": {
"count": 1
- },
- "ts/no-explicit-any": {
- "count": 2
}
},
"web/app/components/workflow-app/hooks/use-workflow-init.ts": {
@@ -6283,9 +6256,6 @@
"web/app/components/workflow/operator/add-block.tsx": {
"no-restricted-imports": {
"count": 1
- },
- "ts/no-explicit-any": {
- "count": 1
}
},
"web/app/components/workflow/operator/hooks.ts": {
diff --git a/packages/contracts/generated/api/console/agent/orpc.gen.ts b/packages/contracts/generated/api/console/agent/orpc.gen.ts
index 5e4a692f244..f8f9ccaa785 100644
--- a/packages/contracts/generated/api/console/agent/orpc.gen.ts
+++ b/packages/contracts/generated/api/console/agent/orpc.gen.ts
@@ -6,6 +6,8 @@ import * as z from 'zod'
import {
zDeleteAgentByAgentIdApiKeysByApiKeyIdPath,
zDeleteAgentByAgentIdApiKeysByApiKeyIdResponse,
+ zDeleteAgentByAgentIdBuildDraftPath,
+ zDeleteAgentByAgentIdBuildDraftResponse,
zDeleteAgentByAgentIdFilesPath,
zDeleteAgentByAgentIdFilesQuery,
zDeleteAgentByAgentIdFilesResponse,
@@ -17,6 +19,8 @@ import {
zGetAgentByAgentIdApiAccessResponse,
zGetAgentByAgentIdApiKeysPath,
zGetAgentByAgentIdApiKeysResponse,
+ zGetAgentByAgentIdBuildDraftPath,
+ zGetAgentByAgentIdBuildDraftResponse,
zGetAgentByAgentIdChatMessagesByMessageIdSuggestedQuestionsPath,
zGetAgentByAgentIdChatMessagesByMessageIdSuggestedQuestionsResponse,
zGetAgentByAgentIdChatMessagesPath,
@@ -76,6 +80,11 @@ import {
zPostAgentByAgentIdApiEnableResponse,
zPostAgentByAgentIdApiKeysPath,
zPostAgentByAgentIdApiKeysResponse,
+ zPostAgentByAgentIdBuildDraftApplyPath,
+ zPostAgentByAgentIdBuildDraftApplyResponse,
+ zPostAgentByAgentIdBuildDraftCheckoutBody,
+ zPostAgentByAgentIdBuildDraftCheckoutPath,
+ zPostAgentByAgentIdBuildDraftCheckoutResponse,
zPostAgentByAgentIdChatMessagesByTaskIdStopPath,
zPostAgentByAgentIdChatMessagesByTaskIdStopResponse,
zPostAgentByAgentIdComposerValidateBody,
@@ -95,6 +104,9 @@ import {
zPostAgentByAgentIdFilesBody,
zPostAgentByAgentIdFilesPath,
zPostAgentByAgentIdFilesResponse,
+ zPostAgentByAgentIdPublishBody,
+ zPostAgentByAgentIdPublishPath,
+ zPostAgentByAgentIdPublishResponse,
zPostAgentByAgentIdSandboxFilesUploadBody,
zPostAgentByAgentIdSandboxFilesUploadPath,
zPostAgentByAgentIdSandboxFilesUploadResponse,
@@ -107,6 +119,9 @@ import {
zPostAgentByAgentIdVersionsByVersionIdRestoreResponse,
zPostAgentResponse,
zPutAgentByAgentIdBody,
+ zPutAgentByAgentIdBuildDraftBody,
+ zPutAgentByAgentIdBuildDraftPath,
+ zPutAgentByAgentIdBuildDraftResponse,
zPutAgentByAgentIdComposerBody,
zPutAgentByAgentIdComposerPath,
zPutAgentByAgentIdComposerResponse,
@@ -206,10 +221,88 @@ export const apiKeys = {
byApiKeyId,
}
+export const post3 = oc
+ .route({
+ inputStructure: 'detailed',
+ method: 'POST',
+ operationId: 'postAgentByAgentIdBuildDraftApply',
+ path: '/agent/{agent_id}/build-draft/apply',
+ tags: ['console'],
+ })
+ .input(z.object({ params: zPostAgentByAgentIdBuildDraftApplyPath }))
+ .output(zPostAgentByAgentIdBuildDraftApplyResponse)
+
+export const apply = {
+ post: post3,
+}
+
+export const post4 = oc
+ .route({
+ inputStructure: 'detailed',
+ method: 'POST',
+ operationId: 'postAgentByAgentIdBuildDraftCheckout',
+ path: '/agent/{agent_id}/build-draft/checkout',
+ tags: ['console'],
+ })
+ .input(
+ z.object({
+ body: zPostAgentByAgentIdBuildDraftCheckoutBody,
+ params: zPostAgentByAgentIdBuildDraftCheckoutPath,
+ }),
+ )
+ .output(zPostAgentByAgentIdBuildDraftCheckoutResponse)
+
+export const checkout = {
+ post: post4,
+}
+
+export const delete2 = oc
+ .route({
+ inputStructure: 'detailed',
+ method: 'DELETE',
+ operationId: 'deleteAgentByAgentIdBuildDraft',
+ path: '/agent/{agent_id}/build-draft',
+ tags: ['console'],
+ })
+ .input(z.object({ params: zDeleteAgentByAgentIdBuildDraftPath }))
+ .output(zDeleteAgentByAgentIdBuildDraftResponse)
+
+export const get4 = oc
+ .route({
+ inputStructure: 'detailed',
+ method: 'GET',
+ operationId: 'getAgentByAgentIdBuildDraft',
+ path: '/agent/{agent_id}/build-draft',
+ tags: ['console'],
+ })
+ .input(z.object({ params: zGetAgentByAgentIdBuildDraftPath }))
+ .output(zGetAgentByAgentIdBuildDraftResponse)
+
+export const put = oc
+ .route({
+ inputStructure: 'detailed',
+ method: 'PUT',
+ operationId: 'putAgentByAgentIdBuildDraft',
+ path: '/agent/{agent_id}/build-draft',
+ tags: ['console'],
+ })
+ .input(
+ z.object({ body: zPutAgentByAgentIdBuildDraftBody, params: zPutAgentByAgentIdBuildDraftPath }),
+ )
+ .output(zPutAgentByAgentIdBuildDraftResponse)
+
+export const buildDraft = {
+ delete: delete2,
+ get: get4,
+ put,
+ apply,
+ checkout,
+}
+
/**
* Get suggested questions for an Agent App message
*/
-export const get4 = oc
+export const get5 = oc
.route({
description: 'Get suggested questions for an Agent App message',
inputStructure: 'detailed',
@@ -222,7 +315,7 @@ export const get4 = oc
.output(zGetAgentByAgentIdChatMessagesByMessageIdSuggestedQuestionsResponse)
export const suggestedQuestions = {
- get: get4,
+ get: get5,
}
export const byMessageId = {
@@ -232,7 +325,7 @@ export const byMessageId = {
/**
* Stop a running Agent App chat message generation
*/
-export const post3 = oc
+export const post5 = oc
.route({
description: 'Stop a running Agent App chat message generation',
inputStructure: 'detailed',
@@ -245,7 +338,7 @@ export const post3 = oc
.output(zPostAgentByAgentIdChatMessagesByTaskIdStopResponse)
export const stop = {
- post: post3,
+ post: post5,
}
export const byTaskId = {
@@ -255,7 +348,7 @@ export const byTaskId = {
/**
* Get Agent App chat messages for a conversation with pagination
*/
-export const get5 = oc
+export const get6 = oc
.route({
description: 'Get Agent App chat messages for a conversation with pagination',
inputStructure: 'detailed',
@@ -273,12 +366,12 @@ export const get5 = oc
.output(zGetAgentByAgentIdChatMessagesResponse)
export const chatMessages = {
- get: get5,
+ get: get6,
byMessageId,
byTaskId,
}
-export const get6 = oc
+export const get7 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@@ -290,10 +383,10 @@ export const get6 = oc
.output(zGetAgentByAgentIdComposerCandidatesResponse)
export const candidates = {
- get: get6,
+ get: get7,
}
-export const post4 = oc
+export const post6 = oc
.route({
inputStructure: 'detailed',
method: 'POST',
@@ -310,10 +403,10 @@ export const post4 = oc
.output(zPostAgentByAgentIdComposerValidateResponse)
export const validate = {
- post: post4,
+ post: post6,
}
-export const get7 = oc
+export const get8 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@@ -324,7 +417,7 @@ export const get7 = oc
.input(z.object({ params: zGetAgentByAgentIdComposerPath }))
.output(zGetAgentByAgentIdComposerResponse)
-export const put = oc
+export const put2 = oc
.route({
inputStructure: 'detailed',
method: 'PUT',
@@ -336,13 +429,13 @@ export const put = oc
.output(zPutAgentByAgentIdComposerResponse)
export const composer = {
- get: get7,
- put,
+ get: get8,
+ put: put2,
candidates,
validate,
}
-export const post5 = oc
+export const post7 = oc
.route({
inputStructure: 'detailed',
method: 'POST',
@@ -355,10 +448,10 @@ export const post5 = oc
.output(zPostAgentByAgentIdCopyResponse)
export const copy = {
- post: post5,
+ post: post7,
}
-export const post6 = oc
+export const post8 = oc
.route({
inputStructure: 'detailed',
method: 'POST',
@@ -370,7 +463,7 @@ export const post6 = oc
.output(zPostAgentByAgentIdDebugConversationRefreshResponse)
export const refresh = {
- post: post6,
+ post: post8,
}
export const debugConversation = {
@@ -380,7 +473,7 @@ export const debugConversation = {
/**
* Time-limited external signed URL for one Agent App drive value
*/
-export const get8 = oc
+export const get9 = oc
.route({
description: 'Time-limited external signed URL for one Agent App drive value',
inputStructure: 'detailed',
@@ -398,13 +491,13 @@ export const get8 = oc
.output(zGetAgentByAgentIdDriveFilesDownloadResponse)
export const download = {
- get: get8,
+ get: get9,
}
/**
* Truncated text preview of one Agent App drive value
*/
-export const get9 = oc
+export const get10 = oc
.route({
description: 'Truncated text preview of one Agent App drive value',
inputStructure: 'detailed',
@@ -422,13 +515,13 @@ export const get9 = oc
.output(zGetAgentByAgentIdDriveFilesPreviewResponse)
export const preview = {
- get: get9,
+ get: get10,
}
/**
* List agent drive entries for an Agent App
*/
-export const get10 = oc
+export const get11 = oc
.route({
description: 'List agent drive entries for an Agent App',
inputStructure: 'detailed',
@@ -446,7 +539,7 @@ export const get10 = oc
.output(zGetAgentByAgentIdDriveFilesResponse)
export const files = {
- get: get10,
+ get: get11,
download,
preview,
}
@@ -454,7 +547,7 @@ export const files = {
/**
* Inspect one drive-backed skill for slash-menu hover/detail UI
*/
-export const get11 = oc
+export const get12 = oc
.route({
description: 'Inspect one drive-backed skill for slash-menu hover/detail UI',
inputStructure: 'detailed',
@@ -467,7 +560,7 @@ export const get11 = oc
.output(zGetAgentByAgentIdDriveSkillsBySkillPathInspectResponse)
export const inspect = {
- get: get11,
+ get: get12,
}
export const bySkillPath = {
@@ -477,7 +570,7 @@ export const bySkillPath = {
/**
* List drive-backed skills for an Agent App
*/
-export const get12 = oc
+export const get13 = oc
.route({
description: 'List drive-backed skills for an Agent App',
inputStructure: 'detailed',
@@ -490,7 +583,7 @@ export const get12 = oc
.output(zGetAgentByAgentIdDriveSkillsResponse)
export const skills = {
- get: get12,
+ get: get13,
bySkillPath,
}
@@ -502,7 +595,7 @@ export const drive = {
/**
* Update an Agent App's presentation features (opener, follow-up, citations, ...)
*/
-export const post7 = oc
+export const post9 = oc
.route({
description: 'Update an Agent App\'s presentation features (opener, follow-up, citations, ...)',
inputStructure: 'detailed',
@@ -517,13 +610,13 @@ export const post7 = oc
.output(zPostAgentByAgentIdFeaturesResponse)
export const features = {
- post: post7,
+ post: post9,
}
/**
* Create or update Agent App message feedback
*/
-export const post8 = oc
+export const post10 = oc
.route({
description: 'Create or update Agent App message feedback',
inputStructure: 'detailed',
@@ -538,13 +631,13 @@ export const post8 = oc
.output(zPostAgentByAgentIdFeedbacksResponse)
export const feedbacks = {
- post: post8,
+ post: post10,
}
/**
* Delete one Agent App drive file by key
*/
-export const delete2 = oc
+export const delete3 = oc
.route({
description: 'Delete one Agent App drive file by key',
inputStructure: 'detailed',
@@ -561,7 +654,7 @@ export const delete2 = oc
/**
* Commit an uploaded file into the Agent App drive under files/
*/
-export const post9 = oc
+export const post11 = oc
.route({
description: 'Commit an uploaded file into the Agent App drive under files/',
inputStructure: 'detailed',
@@ -575,11 +668,11 @@ export const post9 = oc
.output(zPostAgentByAgentIdFilesResponse)
export const files2 = {
- delete: delete2,
- post: post9,
+ delete: delete3,
+ post: post11,
}
-export const get13 = oc
+export const get14 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@@ -591,10 +684,10 @@ export const get13 = oc
.output(zGetAgentByAgentIdLogSourcesResponse)
export const logSources = {
- get: get13,
+ get: get14,
}
-export const get14 = oc
+export const get15 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@@ -611,14 +704,14 @@ export const get14 = oc
.output(zGetAgentByAgentIdLogsByConversationIdMessagesResponse)
export const messages = {
- get: get14,
+ get: get15,
}
export const byConversationId = {
messages,
}
-export const get15 = oc
+export const get16 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@@ -632,14 +725,14 @@ export const get15 = oc
.output(zGetAgentByAgentIdLogsResponse)
export const logs = {
- get: get15,
+ get: get16,
byConversationId,
}
/**
* Get Agent App message details by ID
*/
-export const get16 = oc
+export const get17 = oc
.route({
description: 'Get Agent App message details by ID',
inputStructure: 'detailed',
@@ -652,17 +745,32 @@ export const get16 = oc
.output(zGetAgentByAgentIdMessagesByMessageIdResponse)
export const byMessageId2 = {
- get: get16,
+ get: get17,
}
export const messages2 = {
byMessageId: byMessageId2,
}
+export const post12 = oc
+ .route({
+ inputStructure: 'detailed',
+ method: 'POST',
+ operationId: 'postAgentByAgentIdPublish',
+ path: '/agent/{agent_id}/publish',
+ tags: ['console'],
+ })
+ .input(z.object({ body: zPostAgentByAgentIdPublishBody, params: zPostAgentByAgentIdPublishPath }))
+ .output(zPostAgentByAgentIdPublishResponse)
+
+export const publish = {
+ post: post12,
+}
+
/**
* List workflow apps that reference this Agent App's bound Agent (read-only)
*/
-export const get17 = oc
+export const get18 = oc
.route({
description: 'List workflow apps that reference this Agent App\'s bound Agent (read-only)',
inputStructure: 'detailed',
@@ -675,13 +783,13 @@ export const get17 = oc
.output(zGetAgentByAgentIdReferencingWorkflowsResponse)
export const referencingWorkflows = {
- get: get17,
+ get: get18,
}
/**
* Read a text/binary preview file in an Agent App conversation sandbox
*/
-export const get18 = oc
+export const get19 = oc
.route({
description: 'Read a text/binary preview file in an Agent App conversation sandbox',
inputStructure: 'detailed',
@@ -699,13 +807,13 @@ export const get18 = oc
.output(zGetAgentByAgentIdSandboxFilesReadResponse)
export const read = {
- get: get18,
+ get: get19,
}
/**
* Upload one Agent App sandbox file as a Dify ToolFile mapping
*/
-export const post10 = oc
+export const post13 = oc
.route({
description: 'Upload one Agent App sandbox file as a Dify ToolFile mapping',
inputStructure: 'detailed',
@@ -723,13 +831,13 @@ export const post10 = oc
.output(zPostAgentByAgentIdSandboxFilesUploadResponse)
export const upload = {
- post: post10,
+ post: post13,
}
/**
* List a directory in an Agent App conversation sandbox
*/
-export const get19 = oc
+export const get20 = oc
.route({
description: 'List a directory in an Agent App conversation sandbox',
inputStructure: 'detailed',
@@ -747,7 +855,7 @@ export const get19 = oc
.output(zGetAgentByAgentIdSandboxFilesResponse)
export const files3 = {
- get: get19,
+ get: get20,
read,
upload,
}
@@ -759,7 +867,7 @@ export const sandbox = {
/**
* Upload + standardize a Skill into an Agent App drive
*/
-export const post11 = oc
+export const post14 = oc
.route({
description: 'Upload + standardize a Skill into an Agent App drive',
inputStructure: 'detailed',
@@ -778,13 +886,13 @@ export const post11 = oc
.output(zPostAgentByAgentIdSkillsUploadResponse)
export const upload2 = {
- post: post11,
+ post: post14,
}
/**
* Infer CLI tool + ENV suggestions from a standardized Agent App skill
*/
-export const post12 = oc
+export const post15 = oc
.route({
description: 'Infer CLI tool + ENV suggestions from a standardized Agent App skill',
inputStructure: 'detailed',
@@ -797,13 +905,13 @@ export const post12 = oc
.output(zPostAgentByAgentIdSkillsBySlugInferToolsResponse)
export const inferTools = {
- post: post12,
+ post: post15,
}
/**
* Delete a standardized skill from an Agent App drive
*/
-export const delete3 = oc
+export const delete4 = oc
.route({
description: 'Delete a standardized skill from an Agent App drive',
inputStructure: 'detailed',
@@ -816,7 +924,7 @@ export const delete3 = oc
.output(zDeleteAgentByAgentIdSkillsBySlugResponse)
export const bySlug = {
- delete: delete3,
+ delete: delete4,
inferTools,
}
@@ -825,7 +933,7 @@ export const skills2 = {
bySlug,
}
-export const get20 = oc
+export const get21 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@@ -842,14 +950,14 @@ export const get20 = oc
.output(zGetAgentByAgentIdStatisticsSummaryResponse)
export const summary = {
- get: get20,
+ get: get21,
}
export const statistics = {
summary,
}
-export const post13 = oc
+export const post16 = oc
.route({
inputStructure: 'detailed',
method: 'POST',
@@ -861,10 +969,10 @@ export const post13 = oc
.output(zPostAgentByAgentIdVersionsByVersionIdRestoreResponse)
export const restore = {
- post: post13,
+ post: post16,
}
-export const get21 = oc
+export const get22 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@@ -876,11 +984,11 @@ export const get21 = oc
.output(zGetAgentByAgentIdVersionsByVersionIdResponse)
export const byVersionId = {
- get: get21,
+ get: get22,
restore,
}
-export const get22 = oc
+export const get23 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@@ -892,11 +1000,11 @@ export const get22 = oc
.output(zGetAgentByAgentIdVersionsResponse)
export const versions = {
- get: get22,
+ get: get23,
byVersionId,
}
-export const delete4 = oc
+export const delete5 = oc
.route({
inputStructure: 'detailed',
method: 'DELETE',
@@ -908,7 +1016,7 @@ export const delete4 = oc
.input(z.object({ params: zDeleteAgentByAgentIdPath }))
.output(zDeleteAgentByAgentIdResponse)
-export const get23 = oc
+export const get24 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@@ -919,7 +1027,7 @@ export const get23 = oc
.input(z.object({ params: zGetAgentByAgentIdPath }))
.output(zGetAgentByAgentIdResponse)
-export const put2 = oc
+export const put3 = oc
.route({
inputStructure: 'detailed',
method: 'PUT',
@@ -931,12 +1039,13 @@ export const put2 = oc
.output(zPutAgentByAgentIdResponse)
export const byAgentId = {
- delete: delete4,
- get: get23,
- put: put2,
+ delete: delete5,
+ get: get24,
+ put: put3,
apiAccess,
apiEnable,
apiKeys,
+ buildDraft,
chatMessages,
composer,
copy,
@@ -948,6 +1057,7 @@ export const byAgentId = {
logSources,
logs,
messages: messages2,
+ publish,
referencingWorkflows,
sandbox,
skills: skills2,
@@ -955,7 +1065,7 @@ export const byAgentId = {
versions,
}
-export const get24 = oc
+export const get25 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@@ -966,7 +1076,7 @@ export const get24 = oc
.input(z.object({ query: zGetAgentQuery.optional() }))
.output(zGetAgentResponse)
-export const post14 = oc
+export const post17 = oc
.route({
inputStructure: 'detailed',
method: 'POST',
@@ -979,8 +1089,8 @@ export const post14 = oc
.output(zPostAgentResponse)
export const agent = {
- get: get24,
- post: post14,
+ get: get25,
+ post: post17,
inviteOptions,
byAgentId,
}
diff --git a/packages/contracts/generated/api/console/agent/types.gen.ts b/packages/contracts/generated/api/console/agent/types.gen.ts
index 992d205cb33..d7893563814 100644
--- a/packages/contracts/generated/api/console/agent/types.gen.ts
+++ b/packages/contracts/generated/api/console/agent/types.gen.ts
@@ -107,27 +107,18 @@ export type ApiKeyItem = {
type: string
}
-export type MessageInfiniteScrollPaginationResponse = {
- data: Array
- has_more: boolean
- limit: number
-}
-
-export type SuggestedQuestionsResponse = {
- data: Array
-}
-
-export type SimpleResultResponse = {
+export type AgentSimpleResultResponse = {
result: string
}
-export type AgentAppComposerResponse = {
- active_config_snapshot: AgentConfigSnapshotSummaryResponse
- agent: AgentComposerAgentResponse
- agent_soul: AgentSoulConfig
- save_options: Array
- validation?: ComposerValidationFindingsResponse | null
- variant: 'agent_app'
+export type AgentBuildDraftResponse = {
+ agent_soul: {
+ [key: string]: unknown
+ }
+ draft: {
+ [key: string]: unknown
+ }
+ variant: string
}
export type ComposerSavePayload = {
@@ -148,6 +139,41 @@ export type ComposerSavePayload = {
version_note?: string | null
}
+export type AgentBuildDraftApplyResponse = {
+ draft: {
+ [key: string]: unknown
+ }
+ result: string
+}
+
+export type AgentBuildDraftCheckoutPayload = {
+ force?: boolean
+}
+
+export type MessageInfiniteScrollPaginationResponse = {
+ data: Array
+ has_more: boolean
+ limit: number
+}
+
+export type SuggestedQuestionsResponse = {
+ data: Array
+}
+
+export type SimpleResultResponse = {
+ result: string
+}
+
+export type AgentAppComposerResponse = {
+ active_config_snapshot?: AgentConfigSnapshotSummaryResponse | null
+ agent: AgentComposerAgentResponse
+ agent_soul: AgentSoulConfig
+ draft?: AgentConfigDraftSummaryResponse | null
+ save_options: Array
+ validation?: ComposerValidationFindingsResponse | null
+ variant: 'agent_app'
+}
+
export type AgentComposerCandidatesResponse = {
allowed_node_job_candidates?: AgentComposerNodeJobCandidatesResponse
allowed_soul_candidates?: AgentComposerSoulCandidatesResponse
@@ -294,6 +320,21 @@ export type MessageDetailResponse = {
workflow_run_id?: string | null
}
+export type AgentPublishPayload = {
+ version_note?: string | null
+}
+
+export type AgentPublishResponse = {
+ active_config_snapshot?: {
+ [key: string]: unknown
+ } | null
+ active_config_snapshot_id: string
+ draft?: {
+ [key: string]: unknown
+ } | null
+ result: string
+}
+
export type AgentReferencingWorkflowsResponse = {
data?: Array
}
@@ -359,6 +400,8 @@ export type AgentConfigSnapshotDetailResponse = {
export type AgentConfigSnapshotRestoreResponse = {
active_config_snapshot_id: string
+ draft_config_id?: string | null
+ restored_version_id?: string | null
result: 'success'
}
@@ -497,6 +540,54 @@ export type AgentInviteOptionResponse = {
workflow_node_id?: string | null
}
+export type AgentSoulConfig = {
+ app_features?: AgentSoulAppFeaturesConfig
+ app_variables?: Array
+ env?: AgentSoulEnvConfig
+ files?: AgentSoulFilesConfig
+ human?: AgentSoulHumanConfig
+ knowledge?: AgentSoulKnowledgeConfig
+ memory?: AgentSoulMemoryConfig
+ misc_legacy?: AgentSoulAppFeaturesConfig
+ model?: AgentSoulModelConfig | null
+ prompt?: AgentSoulPromptConfig
+ sandbox?: AgentSoulSandboxConfig
+ schema_version?: number
+ tools?: AgentSoulToolsConfig
+}
+
+export type ComposerBindingPayload = {
+ agent_id?: string | null
+ binding_type: 'inline_agent' | 'roster_agent'
+ current_snapshot_id?: string | null
+}
+
+export type AgentIconType = 'emoji' | 'image' | 'link'
+
+export type WorkflowNodeJobConfig = {
+ declared_outputs?: Array
+ human_contacts?: Array
+ metadata?: WorkflowNodeJobMetadata
+ mode?: WorkflowNodeJobMode
+ previous_node_output_refs?: Array
+ schema_version?: number
+ workflow_prompt?: string
+}
+
+export type ComposerSaveStrategy
+ = | 'node_job_only'
+ | 'save_as_new_agent'
+ | 'save_as_new_version'
+ | 'save_to_current_version'
+ | 'save_to_roster'
+
+export type ComposerSoulLockPayload = {
+ locked?: boolean
+ unlocked_from_version_id?: string | null
+}
+
+export type ComposerVariant = 'agent_app' | 'workflow'
+
export type AgentConfigSnapshotSummaryResponse = {
agent_id?: string | null
created_at?: number | null
@@ -522,58 +613,23 @@ export type AgentComposerAgentResponse = {
status: AgentStatus
}
-export type AgentSoulConfig = {
- app_features?: AgentSoulAppFeaturesConfig
- app_variables?: Array
- env?: AgentSoulEnvConfig
- human?: AgentSoulHumanConfig
- knowledge?: AgentSoulKnowledgeConfig
- memory?: AgentSoulMemoryConfig
- misc_legacy?: AgentSoulAppFeaturesConfig
- model?: AgentSoulModelConfig | null
- prompt?: AgentSoulPromptConfig
- sandbox?: AgentSoulSandboxConfig
- schema_version?: number
- tools?: AgentSoulToolsConfig
+export type AgentConfigDraftSummaryResponse = {
+ account_id?: string | null
+ agent_id: string
+ base_snapshot_id?: string | null
+ created_at?: number | null
+ created_by?: string | null
+ draft_type: AgentConfigDraftType
+ id: string
+ updated_at?: number | null
+ updated_by?: string | null
}
-export type ComposerSaveStrategy
- = | 'node_job_only'
- | 'save_as_new_agent'
- | 'save_as_new_version'
- | 'save_to_current_version'
- | 'save_to_roster'
-
export type ComposerValidationFindingsResponse = {
knowledge_retrieval_placeholder?: Array
warnings?: Array
}
-export type ComposerBindingPayload = {
- agent_id?: string | null
- binding_type: 'inline_agent' | 'roster_agent'
- current_snapshot_id?: string | null
-}
-
-export type AgentIconType = 'emoji' | 'image' | 'link'
-
-export type WorkflowNodeJobConfig = {
- declared_outputs?: Array
- human_contacts?: Array
- metadata?: WorkflowNodeJobMetadata
- mode?: WorkflowNodeJobMode
- previous_node_output_refs?: Array
- schema_version?: number
- workflow_prompt?: string
-}
-
-export type ComposerSoulLockPayload = {
- locked?: boolean
- unlocked_from_version_id?: string | null
-}
-
-export type ComposerVariant = 'agent_app' | 'workflow'
-
export type AgentComposerNodeJobCandidatesResponse = {
declare_output_types?: Array
human_contacts?: Array
@@ -583,8 +639,10 @@ export type AgentComposerNodeJobCandidatesResponse = {
export type AgentComposerSoulCandidatesResponse = {
cli_tools?: Array
dify_tools?: Array
+ files?: Array
human_contacts?: Array
knowledge_sets?: Array
+ skills?: Array
}
export type ComposerCandidateCapabilities = {
@@ -939,6 +997,11 @@ export type AgentSoulEnvConfig = {
variables?: Array
}
+export type AgentSoulFilesConfig = {
+ files?: Array
+ skills?: Array
+}
+
export type AgentSoulHumanConfig = {
contacts?: Array
tools?: Array
@@ -1042,6 +1105,8 @@ export type WorkflowPreviousNodeOutputRef = {
[key: string]: unknown
}
+export type AgentConfigDraftType = 'debug_build' | 'draft'
+
export type DeclaredOutputType = 'array' | 'boolean' | 'file' | 'number' | 'object' | 'string'
export type AgentCliToolConfig = {
@@ -1086,6 +1151,21 @@ export type AgentComposerDifyToolCandidateResponse = {
tools_count?: number | null
}
+export type AgentFileRefConfig = {
+ drive_key?: string | null
+ file_id?: string | null
+ id?: string | null
+ name?: string | null
+ reference?: string | null
+ remote_url?: string | null
+ tenant_id?: string | null
+ transfer_method?: string | null
+ type?: string | null
+ upload_file_id?: string | null
+ url?: string | null
+ [key: string]: unknown
+}
+
export type AgentComposerKnowledgeSetCandidateResponse = {
datasets?: Array
description?: string | null
@@ -1094,6 +1174,21 @@ export type AgentComposerKnowledgeSetCandidateResponse = {
name: string
}
+export type AgentSkillRefConfig = {
+ description?: string | null
+ file_id?: string | null
+ file_refs?: Array
+ full_archive_file_id?: string | null
+ full_archive_key?: string | null
+ id?: string | null
+ manifest_files?: Array | null
+ name?: string | null
+ path?: string | null
+ skill_md_file_id?: string | null
+ skill_md_key?: string | null
+ [key: string]: unknown
+}
+
export type AgentModerationProviderConfig = {
api_based_extension_id?: string | null
inputs_config?: AgentModerationIoConfig | null
@@ -1186,6 +1281,7 @@ export type AgentUserSatisfactionRateStatisticResponse = {
export type AgentConfigRevisionOperation
= | 'create_version'
+ | 'publish_draft'
| 'restore_version'
| 'save_current_version'
| 'save_new_agent'
@@ -1356,21 +1452,6 @@ export type DeclaredOutputFileConfig = {
mime_types?: Array
}
-export type AgentFileRefConfig = {
- drive_key?: string | null
- file_id?: string | null
- id?: string | null
- name?: string | null
- reference?: string | null
- remote_url?: string | null
- tenant_id?: string | null
- transfer_method?: string | null
- type?: string | null
- upload_file_id?: string | null
- url?: string | null
- [key: string]: unknown
-}
-
export type AgentCliToolAuthorizationStatus
= | 'allowed'
| 'authorized'
@@ -1892,6 +1973,86 @@ export type DeleteAgentByAgentIdApiKeysByApiKeyIdResponses = {
export type DeleteAgentByAgentIdApiKeysByApiKeyIdResponse
= DeleteAgentByAgentIdApiKeysByApiKeyIdResponses[keyof DeleteAgentByAgentIdApiKeysByApiKeyIdResponses]
+export type DeleteAgentByAgentIdBuildDraftData = {
+ body?: never
+ path: {
+ agent_id: string
+ }
+ query?: never
+ url: '/agent/{agent_id}/build-draft'
+}
+
+export type DeleteAgentByAgentIdBuildDraftResponses = {
+ 200: AgentSimpleResultResponse
+}
+
+export type DeleteAgentByAgentIdBuildDraftResponse
+ = DeleteAgentByAgentIdBuildDraftResponses[keyof DeleteAgentByAgentIdBuildDraftResponses]
+
+export type GetAgentByAgentIdBuildDraftData = {
+ body?: never
+ path: {
+ agent_id: string
+ }
+ query?: never
+ url: '/agent/{agent_id}/build-draft'
+}
+
+export type GetAgentByAgentIdBuildDraftResponses = {
+ 200: AgentBuildDraftResponse
+}
+
+export type GetAgentByAgentIdBuildDraftResponse
+ = GetAgentByAgentIdBuildDraftResponses[keyof GetAgentByAgentIdBuildDraftResponses]
+
+export type PutAgentByAgentIdBuildDraftData = {
+ body: ComposerSavePayload
+ path: {
+ agent_id: string
+ }
+ query?: never
+ url: '/agent/{agent_id}/build-draft'
+}
+
+export type PutAgentByAgentIdBuildDraftResponses = {
+ 200: AgentBuildDraftResponse
+}
+
+export type PutAgentByAgentIdBuildDraftResponse
+ = PutAgentByAgentIdBuildDraftResponses[keyof PutAgentByAgentIdBuildDraftResponses]
+
+export type PostAgentByAgentIdBuildDraftApplyData = {
+ body?: never
+ path: {
+ agent_id: string
+ }
+ query?: never
+ url: '/agent/{agent_id}/build-draft/apply'
+}
+
+export type PostAgentByAgentIdBuildDraftApplyResponses = {
+ 200: AgentBuildDraftApplyResponse
+}
+
+export type PostAgentByAgentIdBuildDraftApplyResponse
+ = PostAgentByAgentIdBuildDraftApplyResponses[keyof PostAgentByAgentIdBuildDraftApplyResponses]
+
+export type PostAgentByAgentIdBuildDraftCheckoutData = {
+ body: AgentBuildDraftCheckoutPayload
+ path: {
+ agent_id: string
+ }
+ query?: never
+ url: '/agent/{agent_id}/build-draft/checkout'
+}
+
+export type PostAgentByAgentIdBuildDraftCheckoutResponses = {
+ 200: AgentBuildDraftResponse
+}
+
+export type PostAgentByAgentIdBuildDraftCheckoutResponse
+ = PostAgentByAgentIdBuildDraftCheckoutResponses[keyof PostAgentByAgentIdBuildDraftCheckoutResponses]
+
export type GetAgentByAgentIdChatMessagesData = {
body?: never
path: {
@@ -2315,6 +2476,26 @@ export type GetAgentByAgentIdMessagesByMessageIdResponses = {
export type GetAgentByAgentIdMessagesByMessageIdResponse
= GetAgentByAgentIdMessagesByMessageIdResponses[keyof GetAgentByAgentIdMessagesByMessageIdResponses]
+export type PostAgentByAgentIdPublishData = {
+ body: AgentPublishPayload
+ path: {
+ agent_id: string
+ }
+ query?: never
+ url: '/agent/{agent_id}/publish'
+}
+
+export type PostAgentByAgentIdPublishErrors = {
+ 403: unknown
+}
+
+export type PostAgentByAgentIdPublishResponses = {
+ 200: AgentPublishResponse
+}
+
+export type PostAgentByAgentIdPublishResponse
+ = PostAgentByAgentIdPublishResponses[keyof PostAgentByAgentIdPublishResponses]
+
export type GetAgentByAgentIdReferencingWorkflowsData = {
body?: never
path: {
diff --git a/packages/contracts/generated/api/console/agent/zod.gen.ts b/packages/contracts/generated/api/console/agent/zod.gen.ts
index d4ca981006c..feaf6f9052b 100644
--- a/packages/contracts/generated/api/console/agent/zod.gen.ts
+++ b/packages/contracts/generated/api/console/agent/zod.gen.ts
@@ -47,6 +47,37 @@ export const zApiKeyList = z.object({
data: z.array(zApiKeyItem),
})
+/**
+ * AgentSimpleResultResponse
+ */
+export const zAgentSimpleResultResponse = z.object({
+ result: z.string(),
+})
+
+/**
+ * AgentBuildDraftResponse
+ */
+export const zAgentBuildDraftResponse = z.object({
+ agent_soul: z.record(z.string(), z.unknown()),
+ draft: z.record(z.string(), z.unknown()),
+ variant: z.string(),
+})
+
+/**
+ * AgentBuildDraftApplyResponse
+ */
+export const zAgentBuildDraftApplyResponse = z.object({
+ draft: z.record(z.string(), z.unknown()),
+ result: z.string(),
+})
+
+/**
+ * AgentBuildDraftCheckoutPayload
+ */
+export const zAgentBuildDraftCheckoutPayload = z.object({
+ force: z.boolean().optional().default(false),
+})
+
/**
* SuggestedQuestionsResponse
*/
@@ -110,6 +141,23 @@ export const zAgentDriveFilePayload = z.object({
upload_file_id: z.string(),
})
+/**
+ * AgentPublishPayload
+ */
+export const zAgentPublishPayload = z.object({
+ version_note: z.string().nullish(),
+})
+
+/**
+ * AgentPublishResponse
+ */
+export const zAgentPublishResponse = z.object({
+ active_config_snapshot: z.record(z.string(), z.unknown()).nullish(),
+ active_config_snapshot_id: z.string(),
+ draft: z.record(z.string(), z.unknown()).nullish(),
+ result: z.string(),
+})
+
/**
* SandboxReadResponse
*/
@@ -134,6 +182,8 @@ export const zAgentSandboxUploadPayload = z.object({
*/
export const zAgentConfigSnapshotRestoreResponse = z.object({
active_config_snapshot_id: z.string(),
+ draft_config_id: z.string().nullish(),
+ restored_version_id: z.string().nullish(),
result: z.literal('success'),
})
@@ -250,6 +300,46 @@ export const zWorkflowPartial = z.object({
updated_by: z.string().nullish(),
})
+/**
+ * ComposerBindingPayload
+ */
+export const zComposerBindingPayload = z.object({
+ agent_id: z.string().nullish(),
+ binding_type: z.enum(['inline_agent', 'roster_agent']),
+ current_snapshot_id: z.string().nullish(),
+})
+
+/**
+ * AgentIconType
+ *
+ * Supported icon storage formats for Agent roster entries.
+ */
+export const zAgentIconType = z.enum(['emoji', 'image', 'link'])
+
+/**
+ * ComposerSaveStrategy
+ */
+export const zComposerSaveStrategy = z.enum([
+ 'node_job_only',
+ 'save_as_new_agent',
+ 'save_as_new_version',
+ 'save_to_current_version',
+ 'save_to_roster',
+])
+
+/**
+ * ComposerSoulLockPayload
+ */
+export const zComposerSoulLockPayload = z.object({
+ locked: z.boolean().optional().default(true),
+ unlocked_from_version_id: z.string().nullish(),
+})
+
+/**
+ * ComposerVariant
+ */
+export const zComposerVariant = z.enum(['agent_app', 'workflow'])
+
/**
* AgentConfigSnapshotSummaryResponse
*/
@@ -272,46 +362,6 @@ export const zAgentConfigSnapshotListResponse = z.object({
data: z.array(zAgentConfigSnapshotSummaryResponse),
})
-/**
- * ComposerSaveStrategy
- */
-export const zComposerSaveStrategy = z.enum([
- 'node_job_only',
- 'save_as_new_agent',
- 'save_as_new_version',
- 'save_to_current_version',
- 'save_to_roster',
-])
-
-/**
- * ComposerBindingPayload
- */
-export const zComposerBindingPayload = z.object({
- agent_id: z.string().nullish(),
- binding_type: z.enum(['inline_agent', 'roster_agent']),
- current_snapshot_id: z.string().nullish(),
-})
-
-/**
- * AgentIconType
- *
- * Supported icon storage formats for Agent roster entries.
- */
-export const zAgentIconType = z.enum(['emoji', 'image', 'link'])
-
-/**
- * ComposerSoulLockPayload
- */
-export const zComposerSoulLockPayload = z.object({
- locked: z.boolean().optional().default(true),
- unlocked_from_version_id: z.string().nullish(),
-})
-
-/**
- * ComposerVariant
- */
-export const zComposerVariant = z.enum(['agent_app', 'workflow'])
-
/**
* ComposerCandidateCapabilities
*/
@@ -1001,6 +1051,28 @@ export const zWorkflowPreviousNodeOutputRef = z.object({
.nullish(),
})
+/**
+ * AgentConfigDraftType
+ *
+ * Editable Agent Soul draft workspace type.
+ */
+export const zAgentConfigDraftType = z.enum(['debug_build', 'draft'])
+
+/**
+ * AgentConfigDraftSummaryResponse
+ */
+export const zAgentConfigDraftSummaryResponse = z.object({
+ account_id: z.string().nullish(),
+ agent_id: z.string(),
+ base_snapshot_id: z.string().nullish(),
+ created_at: z.int().nullish(),
+ created_by: z.string().nullish(),
+ draft_type: zAgentConfigDraftType,
+ id: z.string(),
+ updated_at: z.int().nullish(),
+ updated_by: z.string().nullish(),
+})
+
/**
* DeclaredOutputType
*/
@@ -1036,6 +1108,62 @@ export const zAgentComposerDifyToolCandidateResponse = z.object({
tools_count: z.int().nullish(),
})
+/**
+ * AgentFileRefConfig
+ */
+export const zAgentFileRefConfig = z.object({
+ drive_key: z.string().max(512).nullish(),
+ file_id: z.string().max(255).nullish(),
+ id: z.string().max(255).nullish(),
+ name: z.string().max(255).nullish(),
+ reference: z.string().max(255).nullish(),
+ remote_url: z.string().nullish(),
+ tenant_id: z.string().max(255).nullish(),
+ transfer_method: z.string().max(64).nullish(),
+ type: z.string().max(64).nullish(),
+ upload_file_id: z.string().max(255).nullish(),
+ url: z.string().nullish(),
+})
+
+/**
+ * WorkflowNodeJobMetadata
+ */
+export const zWorkflowNodeJobMetadata = z.object({
+ agent_soul: z.record(z.string(), z.unknown()).nullish(),
+ file_refs: z.array(zAgentFileRefConfig).nullish(),
+})
+
+/**
+ * AgentSkillRefConfig
+ */
+export const zAgentSkillRefConfig = z.object({
+ description: z.string().nullish(),
+ file_id: z.string().max(255).nullish(),
+ file_refs: z.array(zAgentFileRefConfig).optional(),
+ full_archive_file_id: z.string().max(255).nullish(),
+ full_archive_key: z.string().max(512).nullish(),
+ id: z.string().max(255).nullish(),
+ manifest_files: z.array(z.string()).nullish(),
+ name: z.string().max(255).nullish(),
+ path: z.string().nullish(),
+ skill_md_file_id: z.string().max(255).nullish(),
+ skill_md_key: z.string().max(512).nullish(),
+})
+
+/**
+ * AgentSoulFilesConfig
+ *
+ * Versioned Agent Soul references to drive-backed skills and files.
+ *
+ * File bytes and drive value pointers stay in ``agent_drive_files``. This
+ * section records which drive keys belong to one Agent Soul snapshot so version
+ * restore/copy/runtime use the same skills/files view the user published.
+ */
+export const zAgentSoulFilesConfig = z.object({
+ files: z.array(zAgentFileRefConfig).optional(),
+ skills: z.array(zAgentSkillRefConfig).optional(),
+})
+
/**
* SimpleAccount
*/
@@ -1209,6 +1337,7 @@ export const zAgentStatisticSummaryEnvelopeResponse = z.object({
*/
export const zAgentConfigRevisionOperation = z.enum([
'create_version',
+ 'publish_draft',
'restore_version',
'save_current_version',
'save_new_agent',
@@ -1375,31 +1504,6 @@ export const zDeclaredOutputFileConfig = z.object({
mime_types: z.array(z.string()).optional(),
})
-/**
- * AgentFileRefConfig
- */
-export const zAgentFileRefConfig = z.object({
- drive_key: z.string().max(512).nullish(),
- file_id: z.string().max(255).nullish(),
- id: z.string().max(255).nullish(),
- name: z.string().max(255).nullish(),
- reference: z.string().max(255).nullish(),
- remote_url: z.string().nullish(),
- tenant_id: z.string().max(255).nullish(),
- transfer_method: z.string().max(64).nullish(),
- type: z.string().max(64).nullish(),
- upload_file_id: z.string().max(255).nullish(),
- url: z.string().nullish(),
-})
-
-/**
- * WorkflowNodeJobMetadata
- */
-export const zWorkflowNodeJobMetadata = z.object({
- agent_soul: z.record(z.string(), z.unknown()).nullish(),
- file_refs: z.array(zAgentFileRefConfig).nullish(),
-})
-
/**
* AgentCliToolAuthorizationStatus
*
@@ -1529,8 +1633,10 @@ export const zAgentComposerKnowledgeSetCandidateResponse = z.object({
export const zAgentComposerSoulCandidatesResponse = z.object({
cli_tools: z.array(zAgentCliToolConfig).optional(),
dify_tools: z.array(zAgentComposerDifyToolCandidateResponse).optional(),
+ files: z.array(zAgentFileRefConfig).optional(),
human_contacts: z.array(zAgentHumanContactConfig).optional(),
knowledge_sets: z.array(zAgentComposerKnowledgeSetCandidateResponse).optional(),
+ skills: z.array(zAgentSkillRefConfig).optional(),
})
/**
@@ -2049,6 +2155,7 @@ export const zAgentSoulConfig = z.object({
app_features: zAgentSoulAppFeaturesConfig.optional(),
app_variables: z.array(zAppVariableConfig).optional(),
env: zAgentSoulEnvConfig.optional(),
+ files: zAgentSoulFilesConfig.optional(),
human: zAgentSoulHumanConfig.optional(),
knowledge: zAgentSoulKnowledgeConfig.optional(),
memory: zAgentSoulMemoryConfig.optional(),
@@ -2060,18 +2167,6 @@ export const zAgentSoulConfig = z.object({
tools: zAgentSoulToolsConfig.optional(),
})
-/**
- * AgentAppComposerResponse
- */
-export const zAgentAppComposerResponse = z.object({
- active_config_snapshot: zAgentConfigSnapshotSummaryResponse,
- agent: zAgentComposerAgentResponse,
- agent_soul: zAgentSoulConfig,
- save_options: z.array(zComposerSaveStrategy),
- validation: zComposerValidationFindingsResponse.nullish(),
- variant: z.literal('agent_app'),
-})
-
/**
* ComposerSavePayload
*/
@@ -2093,6 +2188,19 @@ export const zComposerSavePayload = z.object({
version_note: z.string().nullish(),
})
+/**
+ * AgentAppComposerResponse
+ */
+export const zAgentAppComposerResponse = z.object({
+ active_config_snapshot: zAgentConfigSnapshotSummaryResponse.nullish(),
+ agent: zAgentComposerAgentResponse,
+ agent_soul: zAgentSoulConfig,
+ draft: zAgentConfigDraftSummaryResponse.nullish(),
+ save_options: z.array(zComposerSaveStrategy),
+ validation: zComposerValidationFindingsResponse.nullish(),
+ variant: z.literal('agent_app'),
+})
+
/**
* AgentConfigSnapshotDetailResponse
*/
@@ -2470,6 +2578,55 @@ export const zDeleteAgentByAgentIdApiKeysByApiKeyIdPath = z.object({
*/
export const zDeleteAgentByAgentIdApiKeysByApiKeyIdResponse = z.void()
+export const zDeleteAgentByAgentIdBuildDraftPath = z.object({
+ agent_id: z.uuid(),
+})
+
+/**
+ * Agent build draft discarded
+ */
+export const zDeleteAgentByAgentIdBuildDraftResponse = zAgentSimpleResultResponse
+
+export const zGetAgentByAgentIdBuildDraftPath = z.object({
+ agent_id: z.uuid(),
+})
+
+/**
+ * Agent build draft
+ */
+export const zGetAgentByAgentIdBuildDraftResponse = zAgentBuildDraftResponse
+
+export const zPutAgentByAgentIdBuildDraftBody = zComposerSavePayload
+
+export const zPutAgentByAgentIdBuildDraftPath = z.object({
+ agent_id: z.uuid(),
+})
+
+/**
+ * Agent build draft saved
+ */
+export const zPutAgentByAgentIdBuildDraftResponse = zAgentBuildDraftResponse
+
+export const zPostAgentByAgentIdBuildDraftApplyPath = z.object({
+ agent_id: z.uuid(),
+})
+
+/**
+ * Agent build draft applied
+ */
+export const zPostAgentByAgentIdBuildDraftApplyResponse = zAgentBuildDraftApplyResponse
+
+export const zPostAgentByAgentIdBuildDraftCheckoutBody = zAgentBuildDraftCheckoutPayload
+
+export const zPostAgentByAgentIdBuildDraftCheckoutPath = z.object({
+ agent_id: z.uuid(),
+})
+
+/**
+ * Agent build draft checked out
+ */
+export const zPostAgentByAgentIdBuildDraftCheckoutResponse = zAgentBuildDraftResponse
+
export const zGetAgentByAgentIdChatMessagesPath = z.object({
agent_id: z.uuid(),
})
@@ -2738,6 +2895,17 @@ export const zGetAgentByAgentIdMessagesByMessageIdPath = z.object({
*/
export const zGetAgentByAgentIdMessagesByMessageIdResponse = zMessageDetailResponse
+export const zPostAgentByAgentIdPublishBody = zAgentPublishPayload
+
+export const zPostAgentByAgentIdPublishPath = z.object({
+ agent_id: z.uuid(),
+})
+
+/**
+ * Agent draft published
+ */
+export const zPostAgentByAgentIdPublishResponse = zAgentPublishResponse
+
export const zGetAgentByAgentIdReferencingWorkflowsPath = z.object({
agent_id: z.uuid(),
})
diff --git a/packages/contracts/generated/api/console/apps/types.gen.ts b/packages/contracts/generated/api/console/apps/types.gen.ts
index 146e5ee29c9..162ab97f28c 100644
--- a/packages/contracts/generated/api/console/apps/types.gen.ts
+++ b/packages/contracts/generated/api/console/apps/types.gen.ts
@@ -1812,6 +1812,7 @@ export type AgentSoulConfig = {
app_features?: AgentSoulAppFeaturesConfig
app_variables?: Array
env?: AgentSoulEnvConfig
+ files?: AgentSoulFilesConfig
human?: AgentSoulHumanConfig
knowledge?: AgentSoulKnowledgeConfig
memory?: AgentSoulMemoryConfig
@@ -1916,8 +1917,10 @@ export type AgentComposerNodeJobCandidatesResponse = {
export type AgentComposerSoulCandidatesResponse = {
cli_tools?: Array
dify_tools?: Array
+ files?: Array
human_contacts?: Array
knowledge_sets?: Array
+ skills?: Array
}
export type ComposerCandidateCapabilities = {
@@ -2145,6 +2148,11 @@ export type AgentSoulEnvConfig = {
variables?: Array
}
+export type AgentSoulFilesConfig = {
+ files?: Array
+ skills?: Array
+}
+
export type AgentSoulHumanConfig = {
contacts?: Array
tools?: Array
@@ -2303,6 +2311,21 @@ export type AgentComposerDifyToolCandidateResponse = {
tools_count?: number | null
}
+export type AgentFileRefConfig = {
+ drive_key?: string | null
+ file_id?: string | null
+ id?: string | null
+ name?: string | null
+ reference?: string | null
+ remote_url?: string | null
+ tenant_id?: string | null
+ transfer_method?: string | null
+ type?: string | null
+ upload_file_id?: string | null
+ url?: string | null
+ [key: string]: unknown
+}
+
export type AgentComposerKnowledgeSetCandidateResponse = {
datasets?: Array
description?: string | null
@@ -2311,6 +2334,21 @@ export type AgentComposerKnowledgeSetCandidateResponse = {
name: string
}
+export type AgentSkillRefConfig = {
+ description?: string | null
+ file_id?: string | null
+ file_refs?: Array
+ full_archive_file_id?: string | null
+ full_archive_key?: string | null
+ id?: string | null
+ manifest_files?: Array | null
+ name?: string | null
+ path?: string | null
+ skill_md_file_id?: string | null
+ skill_md_key?: string | null
+ [key: string]: unknown
+}
+
export type CheckResultView = {
passed: boolean
reason?: string | null
@@ -2486,21 +2524,6 @@ export type AgentSoulDifyToolConfig = {
tool_name?: string | null
}
-export type AgentFileRefConfig = {
- drive_key?: string | null
- file_id?: string | null
- id?: string | null
- name?: string | null
- reference?: string | null
- remote_url?: string | null
- tenant_id?: string | null
- transfer_method?: string | null
- type?: string | null
- upload_file_id?: string | null
- url?: string | null
- [key: string]: unknown
-}
-
export type OutputErrorStrategy = 'default_value' | 'fail_branch' | 'stop'
export type DeclaredOutputRetryConfig = {
diff --git a/packages/contracts/generated/api/console/apps/zod.gen.ts b/packages/contracts/generated/api/console/apps/zod.gen.ts
index e67a718481b..0583be2f6fb 100644
--- a/packages/contracts/generated/api/console/apps/zod.gen.ts
+++ b/packages/contracts/generated/api/console/apps/zod.gen.ts
@@ -2659,6 +2659,62 @@ export const zAgentComposerDifyToolCandidateResponse = z.object({
tools_count: z.int().nullish(),
})
+/**
+ * AgentFileRefConfig
+ */
+export const zAgentFileRefConfig = z.object({
+ drive_key: z.string().max(512).nullish(),
+ file_id: z.string().max(255).nullish(),
+ id: z.string().max(255).nullish(),
+ name: z.string().max(255).nullish(),
+ reference: z.string().max(255).nullish(),
+ remote_url: z.string().nullish(),
+ tenant_id: z.string().max(255).nullish(),
+ transfer_method: z.string().max(64).nullish(),
+ type: z.string().max(64).nullish(),
+ upload_file_id: z.string().max(255).nullish(),
+ url: z.string().nullish(),
+})
+
+/**
+ * WorkflowNodeJobMetadata
+ */
+export const zWorkflowNodeJobMetadata = z.object({
+ agent_soul: z.record(z.string(), z.unknown()).nullish(),
+ file_refs: z.array(zAgentFileRefConfig).nullish(),
+})
+
+/**
+ * AgentSkillRefConfig
+ */
+export const zAgentSkillRefConfig = z.object({
+ description: z.string().nullish(),
+ file_id: z.string().max(255).nullish(),
+ file_refs: z.array(zAgentFileRefConfig).optional(),
+ full_archive_file_id: z.string().max(255).nullish(),
+ full_archive_key: z.string().max(512).nullish(),
+ id: z.string().max(255).nullish(),
+ manifest_files: z.array(z.string()).nullish(),
+ name: z.string().max(255).nullish(),
+ path: z.string().nullish(),
+ skill_md_file_id: z.string().max(255).nullish(),
+ skill_md_key: z.string().max(512).nullish(),
+})
+
+/**
+ * AgentSoulFilesConfig
+ *
+ * Versioned Agent Soul references to drive-backed skills and files.
+ *
+ * File bytes and drive value pointers stay in ``agent_drive_files``. This
+ * section records which drive keys belong to one Agent Soul snapshot so version
+ * restore/copy/runtime use the same skills/files view the user published.
+ */
+export const zAgentSoulFilesConfig = z.object({
+ files: z.array(zAgentFileRefConfig).optional(),
+ skills: z.array(zAgentSkillRefConfig).optional(),
+})
+
/**
* CheckResultView
*
@@ -2836,31 +2892,6 @@ export const zAgentSoulSandboxConfig = z.object({
provider: z.string().nullish(),
})
-/**
- * AgentFileRefConfig
- */
-export const zAgentFileRefConfig = z.object({
- drive_key: z.string().max(512).nullish(),
- file_id: z.string().max(255).nullish(),
- id: z.string().max(255).nullish(),
- name: z.string().max(255).nullish(),
- reference: z.string().max(255).nullish(),
- remote_url: z.string().nullish(),
- tenant_id: z.string().max(255).nullish(),
- transfer_method: z.string().max(64).nullish(),
- type: z.string().max(64).nullish(),
- upload_file_id: z.string().max(255).nullish(),
- url: z.string().nullish(),
-})
-
-/**
- * WorkflowNodeJobMetadata
- */
-export const zWorkflowNodeJobMetadata = z.object({
- agent_soul: z.record(z.string(), z.unknown()).nullish(),
- file_refs: z.array(zAgentFileRefConfig).nullish(),
-})
-
/**
* OutputErrorStrategy
*
@@ -3026,8 +3057,10 @@ export const zAgentComposerKnowledgeSetCandidateResponse = z.object({
export const zAgentComposerSoulCandidatesResponse = z.object({
cli_tools: z.array(zAgentCliToolConfig).optional(),
dify_tools: z.array(zAgentComposerDifyToolCandidateResponse).optional(),
+ files: z.array(zAgentFileRefConfig).optional(),
human_contacts: z.array(zAgentHumanContactConfig).optional(),
knowledge_sets: z.array(zAgentComposerKnowledgeSetCandidateResponse).optional(),
+ skills: z.array(zAgentSkillRefConfig).optional(),
})
/**
@@ -3599,6 +3632,7 @@ export const zAgentSoulConfig = z.object({
app_features: zAgentSoulAppFeaturesConfig.optional(),
app_variables: z.array(zAppVariableConfig).optional(),
env: zAgentSoulEnvConfig.optional(),
+ files: zAgentSoulFilesConfig.optional(),
human: zAgentSoulHumanConfig.optional(),
knowledge: zAgentSoulKnowledgeConfig.optional(),
memory: zAgentSoulMemoryConfig.optional(),
diff --git a/packages/contracts/generated/api/console/installed-apps/types.gen.ts b/packages/contracts/generated/api/console/installed-apps/types.gen.ts
index f9a5eb01edc..c50f6316dce 100644
--- a/packages/contracts/generated/api/console/installed-apps/types.gen.ts
+++ b/packages/contracts/generated/api/console/installed-apps/types.gen.ts
@@ -31,6 +31,7 @@ export type AudioTranscriptResponse = {
export type ChatMessagePayload = {
conversation_id?: string | null
+ draft_type?: 'debug_build' | 'draft'
files?: Array | null
inputs: {
[key: string]: unknown
diff --git a/packages/contracts/generated/api/console/installed-apps/zod.gen.ts b/packages/contracts/generated/api/console/installed-apps/zod.gen.ts
index a4556058506..2e397c25fb2 100644
--- a/packages/contracts/generated/api/console/installed-apps/zod.gen.ts
+++ b/packages/contracts/generated/api/console/installed-apps/zod.gen.ts
@@ -43,6 +43,7 @@ export const zAudioTranscriptResponse = z.object({
*/
export const zChatMessagePayload = z.object({
conversation_id: z.string().nullish(),
+ draft_type: z.enum(['debug_build', 'draft']).optional().default('draft'),
files: z.array(z.unknown()).nullish(),
inputs: z.record(z.string(), z.unknown()),
model_config: z.record(z.string(), z.unknown()).optional(),