@@ -715,6 +715,148 @@ def test_session_thread_model_fields():
715715 assert "title" not in d # legacy field removed
716716
717717
718+ def test_session_create_params_agent_string_and_object ():
719+ """createSession ``agent`` accepts the Agent ID string (forward-compat)
720+ or an override object; ``environment_variables`` / ``mcp_configs`` are
721+ new top-level fields. Omitted fields are not sent (no null leak)."""
722+ from dashscope .agentstudio .types .params import SessionCreateParams
723+
724+ # String agent — backward compatible.
725+ assert SessionCreateParams (agent = "agent_01" , title = "x" ).to_dict () == {
726+ "agent" : "agent_01" ,
727+ "title" : "x" ,
728+ }
729+ # Override object + new top-level fields (doc §2.3 example).
730+ body = SessionCreateParams (
731+ agent = {
732+ "type" : "agent_with_overrides" ,
733+ "id" : "agent_xxx" ,
734+ "version" : 3 ,
735+ "system" : "你是此 Session 专用的助手。" ,
736+ "tools" : [],
737+ "mcp_servers" : [{"type" : "official" , "name" : "weather" }],
738+ "skills" : [
739+ {
740+ "type" : "customer" ,
741+ "skill_id" : "skill_xxx" ,
742+ "version" : "1.0" ,
743+ }
744+ ],
745+ },
746+ environment_variables = {"LANG" : "zh_CN.UTF-8" },
747+ mcp_configs = [
748+ {"mcp_server_name" : "weather" , "headers" : {"key1" : "value1" }}
749+ ],
750+ ).to_dict ()
751+ assert body ["agent" ]["type" ] == "agent_with_overrides"
752+ assert body ["agent" ]["id" ] == "agent_xxx"
753+ assert body ["environment_variables" ] == {"LANG" : "zh_CN.UTF-8" }
754+ assert body ["mcp_configs" ] == [
755+ {"mcp_server_name" : "weather" , "headers" : {"key1" : "value1" }}
756+ ]
757+ # Omitted optional fields are absent — never sent as null.
758+ for absent in (
759+ "environment_id" ,
760+ "resources" ,
761+ "vault_ids" ,
762+ "metadata" ,
763+ ):
764+ assert absent not in body
765+
766+
767+ def test_session_update_params_patch_and_clear_semantics ():
768+ """updateSession: omitted top-level fields are not sent (keep existing);
769+ ``[]`` / ``{}`` clear; the ``agent`` patch is passed through verbatim so
770+ an explicit ``None`` sub-field serializes to ``null`` (revoke override),
771+ an omitted sub-field stays absent (keep), ``[]`` / ``""`` override empty.
772+ """
773+ from dashscope .agentstudio .types .params import SessionUpdateParams
774+
775+ # Only title — everything else omitted, no null uploaded.
776+ assert SessionUpdateParams (title = "x" ).to_dict () == {"title" : "x" }
777+ # [] / {} explicitly clear (not null).
778+ assert SessionUpdateParams (
779+ vault_ids = [], environment_variables = {}, mcp_configs = [], metadata = {}
780+ ).to_dict () == {
781+ "vault_ids" : [],
782+ "environment_variables" : {},
783+ "mcp_configs" : [],
784+ "metadata" : {},
785+ }
786+ # Full doc §3.3 example body.
787+ body = SessionUpdateParams (
788+ title = "更新后的项目分析" ,
789+ metadata = {"project" : "demo" , "phase" : "review" },
790+ vault_ids = ["vault_project" , "vault_shared" ],
791+ environment_variables = {"LANG" : "zh_CN.UTF-8" , "REPORT_MODE" : "strict" },
792+ agent = {
793+ "system" : "你是本 Session 专用的项目分析助手。" ,
794+ "tools" : [],
795+ "mcp_servers" : [],
796+ "skills" : [
797+ {
798+ "type" : "customer" ,
799+ "skill_id" : "skill_report_writer" ,
800+ "version" : "1.0" ,
801+ }
802+ ],
803+ },
804+ mcp_configs = [
805+ {
806+ "mcp_server_name" : "weather" ,
807+ "headers" : {"X-Tenant-Id" : "demo" },
808+ }
809+ ],
810+ ).to_dict ()
811+ assert body ["agent" ]["system" ] == "你是本 Session 专用的项目分析助手。"
812+ assert body ["agent" ]["skills" ] == [
813+ {
814+ "type" : "customer" ,
815+ "skill_id" : "skill_report_writer" ,
816+ "version" : "1.0" ,
817+ }
818+ ]
819+ assert body ["environment_variables" ] == {
820+ "LANG" : "zh_CN.UTF-8" ,
821+ "REPORT_MODE" : "strict" ,
822+ }
823+ # Agent patch: omitted sub-field absent (keep), None → null (revoke),
824+ # [] / "" override to empty. Mapping passed through verbatim.
825+ patch = SessionUpdateParams (
826+ agent = {"system" : "" , "tools" : None , "skills" : []}
827+ ).to_dict ()["agent" ]
828+ assert patch == {"system" : "" , "tools" : None , "skills" : []}
829+ assert "mcp_servers" not in patch
830+
831+
832+ def test_session_model_hydrates_override_agent_and_new_fields ():
833+ """Session response parses the agent override object and the new
834+ ``environment_variables`` / ``mcp_configs`` fields."""
835+ from dashscope .agentstudio .types import Agent , Session
836+
837+ s = Session (
838+ id = "sesn_1" ,
839+ agent = {
840+ "id" : "agent_01" ,
841+ "type" : "agent_with_overrides" ,
842+ "version" : 3 ,
843+ "system" : "hi" ,
844+ },
845+ environment_variables = {"LANG" : "zh_CN.UTF-8" },
846+ mcp_configs = [
847+ {"mcp_server_name" : "weather" , "headers" : {"k" : "v" }}
848+ ],
849+ )
850+ assert isinstance (s .agent , Agent )
851+ assert s .agent .id == "agent_01"
852+ assert s .agent .type == "agent_with_overrides"
853+ assert s .agent_id == "agent_01" # works for string and object forms
854+ assert s .environment_variables == {"LANG" : "zh_CN.UTF-8" }
855+ assert s .mcp_configs == [
856+ {"mcp_server_name" : "weather" , "headers" : {"k" : "v" }}
857+ ]
858+
859+
718860def test_message_error_and_pending_signal ():
719861 from dashscope .agentstudio .types import parse_message
720862
0 commit comments