diff --git a/api/controllers/console/agent/roster.py b/api/controllers/console/agent/roster.py index d8f5c5c500..fc37845d63 100644 --- a/api/controllers/console/agent/roster.py +++ b/api/controllers/console/agent/roster.py @@ -53,14 +53,20 @@ class AgentIdPath(BaseModel): class AgentAppCreatePayload(BaseModel): name: str = Field(..., min_length=1, description="Agent name") description: str | None = Field(default=None, description="Agent description (max 400 chars)", max_length=400) + role: str = Field(default="", description="Agent role", max_length=255) icon_type: IconType | None = Field(default=None, description="Icon type") icon: str | None = Field(default=None, description="Icon") icon_background: str | None = Field(default=None, description="Icon background color") +class AgentAppUpdatePayload(UpdateAppPayload): + role: str | None = Field(default=None, description="Agent role", max_length=255) + + register_schema_models( console_ns, AgentAppCreatePayload, + AgentAppUpdatePayload, AgentInviteOptionsQuery, AgentIdPath, AppListQuery, @@ -89,20 +95,32 @@ def _serialize_agent_app_detail(app_model) -> dict: app_setting = EnterpriseService.WebAppAuth.get_app_access_mode_by_id(app_id=str(app_model.id)) app_model.access_mode = app_setting.access_mode # type: ignore[attr-defined] - payload = AppDetailWithSite.model_validate(app_model, from_attributes=True).model_dump(mode="json") - agent_id = payload.pop("bound_agent_id", None) - if not agent_id: + agent = _agent_roster_service().get_app_backing_agent(tenant_id=app_model.tenant_id, app_id=app_model.id) + if not agent: raise AgentNotFoundError() - payload["id"] = agent_id + payload = AppDetailWithSite.model_validate(app_model, from_attributes=True).model_dump(mode="json") + payload.pop("bound_agent_id", None) + payload["app_id"] = str(app_model.id) + payload["id"] = agent.id + payload["role"] = agent.role or "" return payload -def _serialize_agent_app_pagination(app_pagination) -> dict: +def _serialize_agent_app_pagination(app_pagination, *, tenant_id: str) -> dict: + app_ids = [str(app.id) for app in app_pagination.items] + agents_by_app_id = _agent_roster_service().load_app_backing_agents_by_app_id( + tenant_id=tenant_id, + app_ids=app_ids, + ) payload = AppPagination.model_validate(app_pagination, from_attributes=True).model_dump(mode="json") for item in payload["data"]: - agent_id = item.pop("bound_agent_id", None) - if agent_id: - item["id"] = agent_id + app_id = item["id"] + item.pop("bound_agent_id", None) + agent = agents_by_app_id.get(app_id) + if agent: + item["app_id"] = app_id + item["id"] = agent.id + item["role"] = agent.role or "" return payload @@ -137,7 +155,7 @@ class AgentAppListApi(Resource): empty = AppPagination(page=args.page, limit=args.limit, total=0, has_more=False, data=[]) return empty.model_dump(mode="json") - return _serialize_agent_app_pagination(app_pagination) + return _serialize_agent_app_pagination(app_pagination, tenant_id=current_tenant_id) @console_ns.expect(console_ns.models[AgentAppCreatePayload.__name__]) @console_ns.response(201, "Agent app created successfully", console_ns.models[AppDetailWithSite.__name__]) @@ -156,6 +174,7 @@ class AgentAppListApi(Resource): name=args.name, description=args.description, mode="agent", + agent_role=args.role, icon_type=args.icon_type, icon=args.icon, icon_background=args.icon_background, @@ -177,7 +196,7 @@ class AgentAppApi(Resource): app_model = _resolve_agent_app_model(tenant_id=tenant_id, agent_id=agent_id) return _serialize_agent_app_detail(app_model) - @console_ns.expect(console_ns.models[UpdateAppPayload.__name__]) + @console_ns.expect(console_ns.models[AgentAppUpdatePayload.__name__]) @console_ns.response(200, "Agent app updated successfully", console_ns.models[AppDetailWithSite.__name__]) @console_ns.response(403, "Insufficient permissions") @console_ns.response(400, "Invalid request parameters") @@ -188,7 +207,7 @@ class AgentAppApi(Resource): @with_current_tenant_id def put(self, tenant_id: str, agent_id: UUID): app_model = _resolve_agent_app_model(tenant_id=tenant_id, agent_id=agent_id) - args = UpdateAppPayload.model_validate(console_ns.payload) + args = AgentAppUpdatePayload.model_validate(console_ns.payload) args_dict: AppService.ArgsDict = { "name": args.name, "description": args.description or "", @@ -197,6 +216,7 @@ class AgentAppApi(Resource): "icon_background": args.icon_background or "", "use_icon_as_answer_icon": args.use_icon_as_answer_icon or False, "max_active_requests": args.max_active_requests or 0, + "role": args.role, } updated = AppService().update_app(app_model, args_dict) return _serialize_agent_app_detail(updated) diff --git a/api/controllers/console/app/app.py b/api/controllers/console/app/app.py index 750530346c..5cd674e4ea 100644 --- a/api/controllers/console/app/app.py +++ b/api/controllers/console/app/app.py @@ -400,6 +400,9 @@ class AppPartial(ResponseModel): has_draft_trigger: bool | None = None # For Agent App type: the roster Agent backing this app (None otherwise). bound_agent_id: str | None = None + # For Agent App responses exposed through /agent. + app_id: str | None = None + role: str | None = None is_starred: bool = False @computed_field(return_type=str | None) # type: ignore @@ -451,6 +454,9 @@ class AppDetailWithSite(AppDetail): site: Site | None = None # For Agent App type: the roster Agent backing this app (None otherwise). bound_agent_id: str | None = None + # For Agent App responses exposed through /agent. + app_id: str | None = None + role: str | None = None @computed_field(return_type=str | None) # type: ignore @property diff --git a/api/openapi/markdown/console-openapi.md b/api/openapi/markdown/console-openapi.md index 4a737dbbdd..688f22e0e8 100644 --- a/api/openapi/markdown/console-openapi.md +++ b/api/openapi/markdown/console-openapi.md @@ -382,7 +382,7 @@ Check if activation token is valid | Required | Schema | | -------- | ------ | -| Yes | **application/json**: [UpdateAppPayload](#updateapppayload)
| +| Yes | **application/json**: [AgentAppUpdatePayload](#agentappupdatepayload)
| #### Responses @@ -11286,6 +11286,7 @@ Default namespace | icon_background | string | Icon background color | No | | icon_type | [IconType](#icontype) | Icon type | No | | name | string | Agent name | Yes | +| role | string | Agent role | No | #### AgentAppFeaturesPayload @@ -11304,6 +11305,19 @@ default (the config form sends the full desired feature state on save). | suggested_questions_after_answer | [AgentSuggestedQuestionsAfterAnswerFeatureConfig](#agentsuggestedquestionsafteranswerfeatureconfig) | Follow-up suggestions config, e.g. {'enabled': true} | No | | text_to_speech | [AgentTextToSpeechFeatureConfig](#agenttexttospeechfeatureconfig) | Text-to-speech config | No | +#### AgentAppUpdatePayload + +| Name | Type | Description | Required | +| ---- | ---- | ----------- | -------- | +| description | string | App description (max 400 chars) | No | +| icon | string | Icon | No | +| icon_background | string | Icon background color | No | +| icon_type | [IconType](#icontype) | Icon type | No | +| max_active_requests | integer | Maximum active requests | No | +| name | string | App name | Yes | +| role | string | Agent role | No | +| use_icon_as_answer_icon | boolean | Use icon as answer icon | No | + #### AgentCliToolAuthorizationStatus Authorization state for Agent-scoped CLI tools. @@ -12502,6 +12516,7 @@ Enum class for api provider schema type. | ---- | ---- | ----------- | -------- | | access_mode | string | | No | | api_base_url | string | | No | +| app_id | string | | No | | bound_agent_id | string | | No | | created_at | integer | | No | | created_by | string | | No | @@ -12518,6 +12533,7 @@ Enum class for api provider schema type. | mode | string | | Yes | | model_config | [ModelConfig](#modelconfig) | | No | | name | string | | Yes | +| role | string | | No | | site | [Site](#site) | | No | | tags | [ [Tag](#tag) ] | | No | | tracing | [JSONValue](#jsonvalue) | | No | @@ -12622,6 +12638,7 @@ AppMCPServer Status Enum | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | | access_mode | string | | No | +| app_id | string | | No | | author_name | string | | No | | bound_agent_id | string | | No | | create_user_name | string | | No | @@ -12639,6 +12656,7 @@ AppMCPServer Status Enum | mode | string | | Yes | | model_config | [ModelConfigPartial](#modelconfigpartial) | | No | | name | string | | Yes | +| role | string | | No | | tags | [ [Tag](#tag) ] | | No | | updated_at | integer | | No | | updated_by | string | | No | diff --git a/api/services/agent/roster_service.py b/api/services/agent/roster_service.py index ed6a24ac1d..21641b2965 100644 --- a/api/services/agent/roster_service.py +++ b/api/services/agent/roster_service.py @@ -282,6 +282,7 @@ class AgentRosterService: app_id: str, name: str, description: str = "", + role: str = "", icon_type: Any = None, icon: str | None = None, icon_background: str | None = None, @@ -298,7 +299,7 @@ class AgentRosterService: tenant_id=tenant_id, name=name, description=description, - role="", + role=role, icon_type=icon_type, icon=icon, icon_background=icon_background, @@ -341,6 +342,21 @@ class AgentRosterService: self._session.flush() return agent + def load_app_backing_agents_by_app_id(self, *, tenant_id: str, app_ids: list[str]) -> dict[str, Agent]: + """Return active app-backed Agents keyed by Agent App id.""" + if not app_ids: + return {} + agents = self._session.scalars( + select(Agent).where( + Agent.tenant_id == tenant_id, + Agent.app_id.in_(app_ids), + Agent.scope == AgentScope.ROSTER, + Agent.source == AgentSource.AGENT_APP, + Agent.status == AgentStatus.ACTIVE, + ) + ).all() + return {agent.app_id: agent for agent in agents if agent.app_id} + def get_app_backing_agent(self, *, tenant_id: str, app_id: str) -> Agent | None: """Return the roster Agent that backs the given Agent App, if any.""" return self._session.scalar( @@ -444,12 +460,36 @@ class AgentRosterService: agent.updated_by = account_id self._session.commit() + @staticmethod + def _visible_version_operations(agent: Agent) -> set[AgentConfigRevisionOperation]: + if agent.source == AgentSource.AGENT_APP: + return {AgentConfigRevisionOperation.SAVE_NEW_VERSION} + return { + AgentConfigRevisionOperation.CREATE_VERSION, + AgentConfigRevisionOperation.SAVE_NEW_VERSION, + AgentConfigRevisionOperation.SAVE_NEW_AGENT, + AgentConfigRevisionOperation.SAVE_TO_ROSTER, + } + def list_agent_versions(self, *, tenant_id: str, agent_id: str) -> list[dict[str, Any]]: - self._get_agent(tenant_id=tenant_id, agent_id=agent_id, roster_only=True) + agent = self._get_agent(tenant_id=tenant_id, agent_id=agent_id, roster_only=True) + visible_version_ids = ( + select(AgentConfigRevision.current_snapshot_id) + .where( + AgentConfigRevision.tenant_id == tenant_id, + AgentConfigRevision.agent_id == agent_id, + AgentConfigRevision.operation.in_(self._visible_version_operations(agent)), + ) + .subquery() + ) versions = list( self._session.scalars( select(AgentConfigSnapshot) - .where(AgentConfigSnapshot.tenant_id == tenant_id, AgentConfigSnapshot.agent_id == agent_id) + .where( + AgentConfigSnapshot.tenant_id == tenant_id, + AgentConfigSnapshot.agent_id == agent_id, + AgentConfigSnapshot.id.in_(select(visible_version_ids.c.current_snapshot_id)), + ) .order_by(AgentConfigSnapshot.version.desc()) ).all() ) @@ -460,7 +500,19 @@ class AgentRosterService: ] def get_agent_version_detail(self, *, tenant_id: str, agent_id: str, version_id: str) -> dict[str, Any]: - self._get_agent(tenant_id=tenant_id, agent_id=agent_id, roster_only=True) + agent = self._get_agent(tenant_id=tenant_id, agent_id=agent_id, roster_only=True) + visible_revision_id = self._session.scalar( + select(AgentConfigRevision.id) + .where( + AgentConfigRevision.tenant_id == tenant_id, + AgentConfigRevision.agent_id == agent_id, + AgentConfigRevision.current_snapshot_id == version_id, + AgentConfigRevision.operation.in_(self._visible_version_operations(agent)), + ) + .limit(1) + ) + if not visible_revision_id: + raise AgentVersionNotFoundError() version = self._get_version(tenant_id=tenant_id, agent_id=agent_id, version_id=version_id) revisions = list( self._session.scalars( diff --git a/api/services/app_service.py b/api/services/app_service.py index d3437a4575..c435a67252 100644 --- a/api/services/app_service.py +++ b/api/services/app_service.py @@ -2,7 +2,7 @@ import json import logging from collections.abc import Sequence from datetime import datetime -from typing import Any, Literal, TypedDict, cast, override +from typing import Any, Literal, NotRequired, TypedDict, cast, override import sqlalchemy as sa from flask_sqlalchemy.pagination import Pagination @@ -63,6 +63,7 @@ class CreateAppParams(BaseModel): name: str = Field(min_length=1) description: str | None = None mode: Literal["chat", "agent-chat", "agent", "advanced-chat", "workflow", "completion"] + agent_role: str = Field(default="", max_length=255) icon_type: str | None = None icon: str | None = None icon_background: str | None = None @@ -90,6 +91,8 @@ class AppService: filters.append(App.mode == AppMode.AGENT_CHAT) elif params.mode == "agent": filters.append(App.mode == AppMode.AGENT) + elif params.mode == "all": + filters.append(App.mode != AppMode.AGENT) if isinstance(params, AppListParams): if params.status: @@ -412,6 +415,7 @@ class AppService: app_id=app.id, name=params.name, description=params.description or "", + role=params.agent_role, icon_type=icon_type, icon=params.icon, icon_background=params.icon_background, @@ -507,6 +511,7 @@ class AppService: icon_background: str use_icon_as_answer_icon: bool max_active_requests: int + role: NotRequired[str | None] @staticmethod def _get_backing_agent_for_update(app: App) -> Agent | None: @@ -538,6 +543,7 @@ class AppService: icon_type: IconType | str | None = None, icon: str | None = None, icon_background: str | None = None, + role: str | None = None, account_id: str | None = None, updated_at: datetime | None = None, ) -> None: @@ -560,6 +566,8 @@ class AppService: agent.icon = icon if icon_background is not None: agent.icon_background = icon_background + if role is not None: + agent.role = role agent.updated_by = account_id if updated_at is not None: agent.updated_at = updated_at @@ -594,6 +602,7 @@ class AppService: icon_type=app.icon_type, icon=app.icon, icon_background=app.icon_background, + role=args.get("role"), account_id=current_user.id, updated_at=app.updated_at, ) diff --git a/api/tests/unit_tests/controllers/console/agent/test_agent_controllers.py b/api/tests/unit_tests/controllers/console/agent/test_agent_controllers.py index acb80075d9..d9bc08920b 100644 --- a/api/tests/unit_tests/controllers/console/agent/test_agent_controllers.py +++ b/api/tests/unit_tests/controllers/console/agent/test_agent_controllers.py @@ -113,6 +113,7 @@ def _app_detail_obj(**overrides): "deleted_tools": [], "site": None, "bound_agent_id": "00000000-0000-0000-0000-000000000001", + "tenant_id": "tenant-1", } data.update(overrides) return SimpleNamespace(**data) @@ -195,6 +196,16 @@ def test_agent_app_list_and_create_use_agent_route( return _app_detail_obj(id="app-created", bound_agent_id="agent-created") monkeypatch.setattr(roster_controller, "AppService", FakeAppService) + monkeypatch.setattr( + roster_controller.AgentRosterService, + "load_app_backing_agents_by_app_id", + lambda _self, **kwargs: {"app-list": SimpleNamespace(id="agent-list", role="List role")}, + ) + monkeypatch.setattr( + roster_controller.AgentRosterService, + "get_app_backing_agent", + lambda _self, **kwargs: SimpleNamespace(id="agent-created", role="Created role"), + ) monkeypatch.setattr( roster_controller.FeatureService, "get_system_features", @@ -208,6 +219,8 @@ def test_agent_app_list_and_create_use_agent_route( assert listed["limit"] == 10 assert listed["total"] == 1 assert listed["data"][0]["id"] == "agent-list" + assert listed["data"][0]["app_id"] == "app-list" + assert listed["data"][0]["role"] == "List role" assert "bound_agent_id" not in listed["data"][0] list_call = cast(dict[str, object], captured["list"]) list_params = cast(Any, list_call["params"]) @@ -222,6 +235,8 @@ def test_agent_app_list_and_create_use_agent_route( assert status == 201 assert created["id"] == "agent-created" + assert created["app_id"] == "app-created" + assert created["role"] == "Created role" assert "bound_agent_id" not in created create_call = cast(dict[str, object], captured["create"]) create_params = cast(Any, create_call["params"]) @@ -240,6 +255,11 @@ def test_agent_app_detail_update_delete_resolve_app_from_agent_id( "get_agent_app_model", lambda _self, **kwargs: app_model, ) + monkeypatch.setattr( + roster_controller.AgentRosterService, + "get_app_backing_agent", + lambda _self, **kwargs: SimpleNamespace(id=agent_id, role="Resolved role"), + ) monkeypatch.setattr( roster_controller.FeatureService, "get_system_features", @@ -262,6 +282,8 @@ def test_agent_app_detail_update_delete_resolve_app_from_agent_id( detail = unwrap(AgentAppApi.get)(AgentAppApi(), "tenant-1", agent_id) assert detail["id"] == agent_id + assert detail["app_id"] == "app-1" + assert detail["role"] == "Resolved role" assert "bound_agent_id" not in detail with app.test_request_context( @@ -272,6 +294,8 @@ def test_agent_app_detail_update_delete_resolve_app_from_agent_id( assert updated["name"] == "Renamed" assert updated["id"] == agent_id + assert updated["app_id"] == "app-1" + assert updated["role"] == "Resolved role" assert "bound_agent_id" not in updated update_call = cast(dict[str, object], captured["update"]) assert update_call["app"] is app_model 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 fc219e45dd..bd2d2899e2 100644 --- a/api/tests/unit_tests/services/agent/test_agent_services.py +++ b/api/tests/unit_tests/services/agent/test_agent_services.py @@ -29,6 +29,7 @@ from services.agent.composer_validator import ComposerConfigValidator from services.agent.errors import InvalidComposerConfigError from services.agent.roster_service import AgentRosterService from services.agent.workflow_publish_service import WorkflowAgentPublishService +from services.app_service import AppListParams, AppService from services.entities.agent_entities import AgentSoulConfig, ComposerSavePayload, ComposerSaveStrategy, ComposerVariant @@ -769,7 +770,7 @@ def test_roster_update_archive_versions_and_detail(monkeypatch): created_by="account-1", created_at=revision_created_at, ) - fake_session = FakeSession(scalars=[[listed_version], [revision]]) + fake_session = FakeSession(scalar=["visible-revision"], scalars=[[listed_version], [revision]]) agent = Agent( id="agent-1", tenant_id="tenant-1", @@ -825,6 +826,7 @@ def test_roster_create_detail_and_lookup_helpers(monkeypatch): payload = roster_service.RosterAgentCreatePayload( name="Analyst", description="desc", + role="Research assistant", icon_type="emoji", icon="A", icon_background="#fff", @@ -838,6 +840,7 @@ def test_roster_create_detail_and_lookup_helpers(monkeypatch): account_id="account-1", app_id="app-1", name="Backing Agent", + role="Support agent", ) found_agent = service._get_agent(tenant_id="tenant-1", agent_id="agent-1") with pytest.raises(roster_service.AgentNotFoundError): @@ -849,9 +852,11 @@ def test_roster_create_detail_and_lookup_helpers(monkeypatch): assert service._load_versions_by_id([]) == {} assert created.name == "Analyst" + assert created.role == "Research assistant" assert created.source == AgentSource.ROSTER assert created.active_config_snapshot_id is not None assert created.active_config_has_model is False + assert backing_agent.role == "Support agent" assert backing_agent.active_config_snapshot_id is not None assert backing_agent.active_config_has_model is False assert found_agent.id == "agent-1" @@ -859,6 +864,30 @@ def test_roster_create_detail_and_lookup_helpers(monkeypatch): assert loaded_versions["version-1"].agent_id == "agent-1" +def test_agent_app_visible_versions_exclude_draft_saves(): + agent_app = Agent(source=AgentSource.AGENT_APP) + roster_agent = Agent(source=AgentSource.ROSTER) + + agent_app_operations = AgentRosterService._visible_version_operations(agent_app) + roster_operations = AgentRosterService._visible_version_operations(roster_agent) + + assert agent_app_operations == {AgentConfigRevisionOperation.SAVE_NEW_VERSION} + assert AgentConfigRevisionOperation.SAVE_CURRENT_VERSION not in agent_app_operations + assert AgentConfigRevisionOperation.CREATE_VERSION in roster_operations + assert AgentConfigRevisionOperation.SAVE_CURRENT_VERSION not in roster_operations + + +def test_app_list_all_excludes_agent_apps_by_default(): + filters = AppService._build_app_list_filters( + "account-1", + "tenant-1", + AppListParams(mode="all"), + ) + sql = " ".join(str(filter_) for filter_ in filters) + + assert "apps.mode != :mode_1" in sql + + def test_validator_dict_helpers_wrap_validation_errors(): valid_soul = ComposerConfigValidator.validate_agent_soul_dict({"prompt": {"system_prompt": "x"}}) valid_node_job = ComposerConfigValidator.validate_node_job_dict({"workflow_prompt": "x"}) diff --git a/packages/contracts/generated/api/console/agent/types.gen.ts b/packages/contracts/generated/api/console/agent/types.gen.ts index 08a470b8c5..a177953170 100644 --- a/packages/contracts/generated/api/console/agent/types.gen.ts +++ b/packages/contracts/generated/api/console/agent/types.gen.ts @@ -18,11 +18,13 @@ export type AgentAppCreatePayload = { icon_background?: string | null icon_type?: IconType | null name: string + role?: string } export type AppDetailWithSite = { access_mode?: string | null api_base_url?: string | null + app_id?: string | null bound_agent_id?: string | null created_at?: number | null created_by?: string | null @@ -39,6 +41,7 @@ export type AppDetailWithSite = { mode: string model_config?: ModelConfig | null name: string + role?: string | null site?: Site | null tags?: Array tracing?: JsonValue | null @@ -56,13 +59,14 @@ export type AgentInviteOptionsResponse = { total: number } -export type UpdateAppPayload = { +export type AgentAppUpdatePayload = { description?: string | null icon?: string | null icon_background?: string | null icon_type?: IconType | null max_active_requests?: number | null name: string + role?: string | null use_icon_as_answer_icon?: boolean | null } @@ -255,6 +259,7 @@ export type AgentConfigSnapshotDetailResponse = { export type AppPartial = { access_mode?: string | null + app_id?: string | null author_name?: string | null bound_agent_id?: string | null create_user_name?: string | null @@ -272,6 +277,7 @@ export type AppPartial = { mode: string model_config?: ModelConfigPartial | null name: string + role?: string | null tags?: Array updated_at?: number | null updated_by?: string | null @@ -1219,6 +1225,7 @@ export type AppPaginationWritable = { export type AppDetailWithSiteWritable = { access_mode?: string | null api_base_url?: string | null + app_id?: string | null bound_agent_id?: string | null created_at?: number | null created_by?: string | null @@ -1234,6 +1241,7 @@ export type AppDetailWithSiteWritable = { mode: string model_config?: ModelConfig | null name: string + role?: string | null site?: SiteWritable | null tags?: Array tracing?: JsonValue | null @@ -1245,6 +1253,7 @@ export type AppDetailWithSiteWritable = { export type AppPartialWritable = { access_mode?: string | null + app_id?: string | null author_name?: string | null bound_agent_id?: string | null create_user_name?: string | null @@ -1261,6 +1270,7 @@ export type AppPartialWritable = { mode: string model_config?: ModelConfigPartial | null name: string + role?: string | null tags?: Array updated_at?: number | null updated_by?: string | null @@ -1387,7 +1397,7 @@ export type GetAgentByAgentIdResponses = { export type GetAgentByAgentIdResponse = GetAgentByAgentIdResponses[keyof GetAgentByAgentIdResponses] export type PutAgentByAgentIdData = { - body: UpdateAppPayload + body: AgentAppUpdatePayload path: { agent_id: string } diff --git a/packages/contracts/generated/api/console/agent/zod.gen.ts b/packages/contracts/generated/api/console/agent/zod.gen.ts index 8d5ca65443..41e16de3b3 100644 --- a/packages/contracts/generated/api/console/agent/zod.gen.ts +++ b/packages/contracts/generated/api/console/agent/zod.gen.ts @@ -92,18 +92,20 @@ export const zAgentAppCreatePayload = z.object({ icon_background: z.string().nullish(), icon_type: zIconType.nullish(), name: z.string().min(1), + role: z.string().max(255).optional().default(''), }) /** - * UpdateAppPayload + * AgentAppUpdatePayload */ -export const zUpdateAppPayload = z.object({ +export const zAgentAppUpdatePayload = z.object({ description: z.string().max(400).nullish(), icon: z.string().nullish(), icon_background: z.string().nullish(), icon_type: zIconType.nullish(), max_active_requests: z.int().nullish(), name: z.string().min(1), + role: z.string().max(255).nullish(), use_icon_as_answer_icon: z.boolean().nullish(), }) @@ -473,6 +475,7 @@ export const zModelConfigPartial = z.object({ */ export const zAppPartial = z.object({ access_mode: z.string().nullish(), + app_id: z.string().nullish(), author_name: z.string().nullish(), bound_agent_id: z.string().nullish(), create_user_name: z.string().nullish(), @@ -490,6 +493,7 @@ export const zAppPartial = z.object({ mode: z.string(), model_config: zModelConfigPartial.nullish(), name: z.string(), + role: z.string().nullish(), tags: z.array(zTag).optional(), updated_at: z.int().nullish(), updated_by: z.string().nullish(), @@ -531,6 +535,7 @@ export const zModelConfig = z.object({ export const zAppDetailWithSite = z.object({ access_mode: z.string().nullish(), api_base_url: z.string().nullish(), + app_id: z.string().nullish(), bound_agent_id: z.string().nullish(), created_at: z.int().nullish(), created_by: z.string().nullish(), @@ -547,6 +552,7 @@ export const zAppDetailWithSite = z.object({ mode: z.string(), model_config: zModelConfig.nullish(), name: z.string(), + role: z.string().nullish(), site: zSite.nullish(), tags: z.array(zTag).optional(), tracing: zJsonValue.nullish(), @@ -1729,6 +1735,7 @@ export const zMessageInfiniteScrollPaginationResponse = z.object({ */ export const zAppPartialWritable = z.object({ access_mode: z.string().nullish(), + app_id: z.string().nullish(), author_name: z.string().nullish(), bound_agent_id: z.string().nullish(), create_user_name: z.string().nullish(), @@ -1745,6 +1752,7 @@ export const zAppPartialWritable = z.object({ mode: z.string(), model_config: zModelConfigPartial.nullish(), name: z.string(), + role: z.string().nullish(), tags: z.array(zTag).optional(), updated_at: z.int().nullish(), updated_by: z.string().nullish(), @@ -1788,6 +1796,7 @@ export const zSiteWritable = z.object({ export const zAppDetailWithSiteWritable = z.object({ access_mode: z.string().nullish(), api_base_url: z.string().nullish(), + app_id: z.string().nullish(), bound_agent_id: z.string().nullish(), created_at: z.int().nullish(), created_by: z.string().nullish(), @@ -1803,6 +1812,7 @@ export const zAppDetailWithSiteWritable = z.object({ mode: z.string(), model_config: zModelConfig.nullish(), name: z.string(), + role: z.string().nullish(), site: zSiteWritable.nullish(), tags: z.array(zTag).optional(), tracing: zJsonValue.nullish(), @@ -1880,7 +1890,7 @@ export const zGetAgentByAgentIdPath = z.object({ */ export const zGetAgentByAgentIdResponse = zAppDetailWithSite -export const zPutAgentByAgentIdBody = zUpdateAppPayload +export const zPutAgentByAgentIdBody = zAgentAppUpdatePayload export const zPutAgentByAgentIdPath = z.object({ agent_id: z.string(), diff --git a/packages/contracts/generated/api/console/apps/types.gen.ts b/packages/contracts/generated/api/console/apps/types.gen.ts index 4db89cbe63..81842742f5 100644 --- a/packages/contracts/generated/api/console/apps/types.gen.ts +++ b/packages/contracts/generated/api/console/apps/types.gen.ts @@ -24,6 +24,7 @@ export type CreateAppPayload = { export type AppDetailWithSite = { access_mode?: string | null api_base_url?: string | null + app_id?: string | null bound_agent_id?: string | null created_at?: number | null created_by?: string | null @@ -40,6 +41,7 @@ export type AppDetailWithSite = { mode: string model_config?: ModelConfig | null name: string + role?: string | null site?: Site | null tags?: Array tracing?: JsonValue | null @@ -1153,6 +1155,7 @@ export type ApiKeyItem = { export type AppPartial = { access_mode?: string | null + app_id?: string | null author_name?: string | null bound_agent_id?: string | null create_user_name?: string | null @@ -1170,6 +1173,7 @@ export type AppPartial = { mode: string model_config?: ModelConfigPartial | null name: string + role?: string | null tags?: Array updated_at?: number | null updated_by?: string | null @@ -2540,6 +2544,7 @@ export type AppPaginationWritable = { export type AppDetailWithSiteWritable = { access_mode?: string | null api_base_url?: string | null + app_id?: string | null bound_agent_id?: string | null created_at?: number | null created_by?: string | null @@ -2555,6 +2560,7 @@ export type AppDetailWithSiteWritable = { mode: string model_config?: ModelConfig | null name: string + role?: string | null site?: SiteWritable | null tags?: Array tracing?: JsonValue | null @@ -2589,6 +2595,7 @@ export type WorkflowCommentDetailWritable = { export type AppPartialWritable = { access_mode?: string | null + app_id?: string | null author_name?: string | null bound_agent_id?: string | null create_user_name?: string | null @@ -2605,6 +2612,7 @@ export type AppPartialWritable = { mode: string model_config?: ModelConfigPartial | null name: string + role?: string | null tags?: Array updated_at?: number | null updated_by?: string | null diff --git a/packages/contracts/generated/api/console/apps/zod.gen.ts b/packages/contracts/generated/api/console/apps/zod.gen.ts index 72dd269231..94e4a8a3aa 100644 --- a/packages/contracts/generated/api/console/apps/zod.gen.ts +++ b/packages/contracts/generated/api/console/apps/zod.gen.ts @@ -1946,6 +1946,7 @@ export const zModelConfigPartial = z.object({ */ export const zAppPartial = z.object({ access_mode: z.string().nullish(), + app_id: z.string().nullish(), author_name: z.string().nullish(), bound_agent_id: z.string().nullish(), create_user_name: z.string().nullish(), @@ -1963,6 +1964,7 @@ export const zAppPartial = z.object({ mode: z.string(), model_config: zModelConfigPartial.nullish(), name: z.string(), + role: z.string().nullish(), tags: z.array(zTag).optional(), updated_at: z.int().nullish(), updated_by: z.string().nullish(), @@ -2004,6 +2006,7 @@ export const zModelConfig = z.object({ export const zAppDetailWithSite = z.object({ access_mode: z.string().nullish(), api_base_url: z.string().nullish(), + app_id: z.string().nullish(), bound_agent_id: z.string().nullish(), created_at: z.int().nullish(), created_by: z.string().nullish(), @@ -2020,6 +2023,7 @@ export const zAppDetailWithSite = z.object({ mode: z.string(), model_config: zModelConfig.nullish(), name: z.string(), + role: z.string().nullish(), site: zSite.nullish(), tags: z.array(zTag).optional(), tracing: zJsonValue.nullish(), @@ -3433,6 +3437,7 @@ export const zGeneratedAppResponseWritable = zJsonValue */ export const zAppPartialWritable = z.object({ access_mode: z.string().nullish(), + app_id: z.string().nullish(), author_name: z.string().nullish(), bound_agent_id: z.string().nullish(), create_user_name: z.string().nullish(), @@ -3449,6 +3454,7 @@ export const zAppPartialWritable = z.object({ mode: z.string(), model_config: zModelConfigPartial.nullish(), name: z.string(), + role: z.string().nullish(), tags: z.array(zTag).optional(), updated_at: z.int().nullish(), updated_by: z.string().nullish(), @@ -3492,6 +3498,7 @@ export const zSiteWritable = z.object({ export const zAppDetailWithSiteWritable = z.object({ access_mode: z.string().nullish(), api_base_url: z.string().nullish(), + app_id: z.string().nullish(), bound_agent_id: z.string().nullish(), created_at: z.int().nullish(), created_by: z.string().nullish(), @@ -3507,6 +3514,7 @@ export const zAppDetailWithSiteWritable = z.object({ mode: z.string(), model_config: zModelConfig.nullish(), name: z.string(), + role: z.string().nullish(), site: zSiteWritable.nullish(), tags: z.array(zTag).optional(), tracing: zJsonValue.nullish(),