prism-models 0.6.6__py3-none-any.whl → 0.7.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
prism_models/__init__.py CHANGED
@@ -3,7 +3,15 @@
3
3
  __version__ = "0.1.0"
4
4
 
5
5
 
6
- from prism_models.agent_profile import Agent, AgentCollectionAccess, AgentProfile, AgentProfileStatus, Profile, ProfileCollectionAccess
6
+ from prism_models.agent_profile import (
7
+ Agent,
8
+ AgentCollectionAccess,
9
+ AgentProfile,
10
+ AgentProfileStatus,
11
+ ContactProfile,
12
+ Profile,
13
+ ProfileCollectionAccess,
14
+ )
7
15
  from prism_models.base import POSTGRES_NAMING_CONVENTION, Base, BaseModel, TimestampMixin
8
16
  from prism_models.chat import Contact, Conversation, ConversationMessage, ConversationMessageMetadata, UserPreferences
9
17
  from prism_models.content import Chunk, ChunkConfig, Collection, CollectionDocument, Document, IntegrationConfig, Source, Vector
@@ -24,6 +32,7 @@ __all__ = [
24
32
  "Collection",
25
33
  "CollectionDocument",
26
34
  "Contact",
35
+ "ContactProfile",
27
36
  "Conversation",
28
37
  "ConversationMessage",
29
38
  "ConversationMessageMetadata",
@@ -42,6 +42,37 @@ class Profile(BaseModel):
42
42
  def __repr__(self) -> str:
43
43
  return f"<Profile(id={self.id}, name='{self.name}', active={self.is_active})>"
44
44
 
45
+
46
+ class ContactProfile(BaseModel):
47
+ """Association between Contact and Profile."""
48
+
49
+ contact_id: Mapped[int] = mapped_column(
50
+ Integer,
51
+ ForeignKey("contact.id", ondelete="CASCADE"),
52
+ nullable=False,
53
+ index=True,
54
+ )
55
+ profile_id: Mapped[int] = mapped_column(
56
+ Integer,
57
+ ForeignKey("profile.id", ondelete="CASCADE"),
58
+ nullable=False,
59
+ index=True,
60
+ )
61
+ assigned_by_contact_id: Mapped[int | None] = mapped_column(
62
+ Integer,
63
+ ForeignKey("contact.id", ondelete="SET NULL"),
64
+ nullable=True,
65
+ index=True,
66
+ )
67
+
68
+ contact: Mapped["Contact"] = relationship(foreign_keys=[contact_id], back_populates="contact_profiles")
69
+ profile: Mapped["Profile"] = relationship()
70
+ assigned_by_contact: Mapped["Contact"] = relationship(foreign_keys=[assigned_by_contact_id])
71
+
72
+ __table_args__ = (
73
+ UniqueConstraint("contact_id", "profile_id", name="uq_contact_profile"),
74
+ )
75
+
45
76
  class AgentType(str, Enum):
46
77
  ORCHESTRATOR_AGENT = "ORCHESTRATOR"
47
78
  DOMAIN_AGENT = "DOMAIN"
prism_models/chat.py CHANGED
@@ -39,7 +39,7 @@ class ContactRole(PyEnum):
39
39
  ADMIN = "ADMIN"
40
40
  MANAGER = "MANAGER"
41
41
  USER = "USER"
42
-
42
+
43
43
 
44
44
 
45
45
  class ConversationType(PyEnum):
@@ -81,6 +81,7 @@ class Contact(ChatSchemaMixin, BaseModel):
81
81
  Relationships:
82
82
  - conversations: One-to-many relationship with Conversation model
83
83
  - user_preferences: One-to-one relationship with UserPreferences model
84
+ - contact_profiles: One-to-many relationship with ContactProfile model
84
85
  """
85
86
 
86
87
  email = Column(String(300), nullable=True)
@@ -111,7 +112,7 @@ class Contact(ChatSchemaMixin, BaseModel):
111
112
  Enum(ContactRole),
112
113
  default=ContactRole.USER,
113
114
  nullable=False,
114
- server_default="VIEWER"
115
+ server_default="USER"
115
116
  )
116
117
  manager_contact_id = Column(
117
118
  Integer,
@@ -137,6 +138,12 @@ class Contact(ChatSchemaMixin, BaseModel):
137
138
  cascade="all, delete-orphan",
138
139
  uselist=False # One-to-one relationship
139
140
  )
141
+ contact_profiles: Mapped[list["ContactProfile"]] = relationship(
142
+ "ContactProfile",
143
+ back_populates="contact",
144
+ cascade="all, delete-orphan",
145
+ foreign_keys="ContactProfile.contact_id",
146
+ )
140
147
 
141
148
 
142
149
  class UserPreferences(BaseModel):
@@ -37,7 +37,7 @@ def upgrade() -> None:
37
37
  op.add_column('contact', sa.Column('manager_contact_id', sa.Integer(), nullable=True))
38
38
  op.create_index(op.f('contact_manager_contact_id_idx'), 'contact', ['manager_contact_id'], unique=False)
39
39
  op.create_foreign_key(op.f('contact_manager_contact_id_fkey'), 'contact', 'contact', ['manager_contact_id'], ['id'], ondelete='SET NULL')
40
- op.drop_index(op.f('idx_document_title_trgm'), table_name='document', postgresql_ops={'title': 'gin_trgm_ops'}, postgresql_using='gin')
40
+ op.drop_index(op.f('idx_document_title_trgm'), table_name='document', postgresql_ops={'title': 'gin_trgm_ops'}, postgresql_using='gin', if_exists=True)
41
41
  # ### end Alembic commands ###
42
42
 
43
43
 
@@ -0,0 +1,54 @@
1
+ """Changed user role enums
2
+
3
+ Revision ID: 147509a82af8
4
+ Revises: 4d9291a3acb1
5
+ Create Date: 2026-01-14 17:42:10.143289
6
+
7
+ """
8
+ from typing import Sequence, Union
9
+
10
+ from alembic import op
11
+ import sqlalchemy as sa
12
+
13
+
14
+ # revision identifiers, used by Alembic.
15
+ revision: str = '147509a82af8'
16
+ down_revision: Union[str, Sequence[str], None] = '4d9291a3acb1'
17
+ branch_labels: Union[str, Sequence[str], None] = None
18
+ depends_on: Union[str, Sequence[str], None] = None
19
+
20
+
21
+ def upgrade() -> None:
22
+ """Upgrade schema."""
23
+ # ### commands auto generated by Alembic - please adjust! ###
24
+ op.execute("CREATE TYPE contactrole_new AS ENUM ('ADMIN', 'MANAGER', 'USER')")
25
+ op.execute("ALTER TABLE contact ALTER COLUMN contact_role DROP DEFAULT")
26
+ op.execute(
27
+ "ALTER TABLE contact ALTER COLUMN contact_role TYPE contactrole_new "
28
+ "USING (CASE "
29
+ "WHEN contact_role::text IN ('ADMIN', 'MANAGER') THEN contact_role::text "
30
+ "ELSE 'USER' "
31
+ "END)::contactrole_new"
32
+ )
33
+ op.execute("ALTER TABLE contact ALTER COLUMN contact_role SET DEFAULT 'USER'")
34
+ op.execute("DROP TYPE contactrole")
35
+ op.execute("ALTER TYPE contactrole_new RENAME TO contactrole")
36
+ # ### end Alembic commands ###
37
+
38
+
39
+ def downgrade() -> None:
40
+ """Downgrade schema."""
41
+ # ### commands auto generated by Alembic - please adjust! ###
42
+ op.execute("CREATE TYPE contactrole_old AS ENUM ('ADMIN', 'ACCOUNT_ADMIN', 'MANAGER', 'VIEWER')")
43
+ op.execute("ALTER TABLE contact ALTER COLUMN contact_role DROP DEFAULT")
44
+ op.execute(
45
+ "ALTER TABLE contact ALTER COLUMN contact_role TYPE contactrole_old "
46
+ "USING (CASE "
47
+ "WHEN contact_role::text IN ('ADMIN', 'MANAGER') THEN contact_role::text "
48
+ "ELSE 'VIEWER' "
49
+ "END)::contactrole_old"
50
+ )
51
+ op.execute("ALTER TABLE contact ALTER COLUMN contact_role SET DEFAULT 'VIEWER'")
52
+ op.execute("DROP TYPE contactrole")
53
+ op.execute("ALTER TYPE contactrole_old RENAME TO contactrole")
54
+ # ### end Alembic commands ###
@@ -0,0 +1,71 @@
1
+ """Add contact_profile table
2
+
3
+ Revision ID: 3b7d0b2e9f5a
4
+ Revises: 147509a82af8
5
+ Create Date: 2026-01-15 10:10:00.000000
6
+
7
+ """
8
+
9
+ from typing import Sequence, Union
10
+
11
+ import sqlalchemy as sa
12
+ from alembic import op
13
+
14
+
15
+ # revision identifiers, used by Alembic.
16
+ revision: str = "3b7d0b2e9f5a"
17
+ down_revision: Union[str, Sequence[str], None] = "147509a82af8"
18
+ branch_labels: Union[str, Sequence[str], None] = None
19
+ depends_on: Union[str, Sequence[str], None] = None
20
+
21
+
22
+ def upgrade() -> None:
23
+ """Upgrade schema."""
24
+ op.create_table(
25
+ "contact_profile",
26
+ sa.Column("contact_id", sa.Integer(), nullable=False),
27
+ sa.Column("profile_id", sa.Integer(), nullable=False),
28
+ sa.Column("assigned_by_contact_id", sa.Integer(), nullable=True),
29
+ sa.Column("id", sa.Integer(), nullable=False),
30
+ sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("now()"), nullable=False),
31
+ sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("now()"), nullable=False),
32
+ sa.Column("deleted_at", sa.DateTime(timezone=True), nullable=True),
33
+ sa.ForeignKeyConstraint(
34
+ ["assigned_by_contact_id"],
35
+ ["contact.id"],
36
+ name=op.f("contact_profile_assigned_by_contact_id_fkey"),
37
+ ondelete="SET NULL",
38
+ ),
39
+ sa.ForeignKeyConstraint(
40
+ ["contact_id"],
41
+ ["contact.id"],
42
+ name=op.f("contact_profile_contact_id_fkey"),
43
+ ondelete="CASCADE",
44
+ ),
45
+ sa.ForeignKeyConstraint(
46
+ ["profile_id"],
47
+ ["profile.id"],
48
+ name=op.f("contact_profile_profile_id_fkey"),
49
+ ondelete="CASCADE",
50
+ ),
51
+ sa.PrimaryKeyConstraint("id", name=op.f("contact_profile_pkey")),
52
+ sa.UniqueConstraint("contact_id", "profile_id", name="uq_contact_profile"),
53
+ )
54
+ op.create_index(
55
+ op.f("contact_profile_assigned_by_contact_id_idx"),
56
+ "contact_profile",
57
+ ["assigned_by_contact_id"],
58
+ unique=False,
59
+ )
60
+ op.create_index(op.f("contact_profile_contact_id_idx"), "contact_profile", ["contact_id"], unique=False)
61
+ op.create_index(op.f("contact_profile_id_idx"), "contact_profile", ["id"], unique=False)
62
+ op.create_index(op.f("contact_profile_profile_id_idx"), "contact_profile", ["profile_id"], unique=False)
63
+
64
+
65
+ def downgrade() -> None:
66
+ """Downgrade schema."""
67
+ op.drop_index(op.f("contact_profile_profile_id_idx"), table_name="contact_profile")
68
+ op.drop_index(op.f("contact_profile_id_idx"), table_name="contact_profile")
69
+ op.drop_index(op.f("contact_profile_contact_id_idx"), table_name="contact_profile")
70
+ op.drop_index(op.f("contact_profile_assigned_by_contact_id_idx"), table_name="contact_profile")
71
+ op.drop_table("contact_profile")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: prism-models
3
- Version: 0.6.6
3
+ Version: 0.7.3
4
4
  Requires-Python: >=3.12
5
5
  Requires-Dist: sqlalchemy[asyncio]>=2.0.0
6
6
  Requires-Dist: alembic>=1.16.0
@@ -1,7 +1,7 @@
1
- prism_models/__init__.py,sha256=Z4IOhsD992zLMKmo9a2eWdcxThSrl2N9igGn_mRKM_4,1420
2
- prism_models/agent_profile.py,sha256=SSZhrMSGYXr2Skc3niw1SiCZGK5JhwUyyH7Au-UXuPQ,7190
1
+ prism_models/__init__.py,sha256=jD-ASYrK4-FW1txMuUnUCwvZCHN7d9ko8b_lCLuZS9s,1491
2
+ prism_models/agent_profile.py,sha256=sNO9NfOpOFXgpkvxMry-5rcHNfFdWXtMV6b45JA0Wr8,8159
3
3
  prism_models/base.py,sha256=Ka8zNToTiTG0jNgzqqj2goGmPXt8zxuuSMYvotnb8wY,2281
4
- prism_models/chat.py,sha256=IktJGUCKqrSWLBSD6XpuZBSbuMUYVNApu_BEZtjf6A8,14909
4
+ prism_models/chat.py,sha256=0nsp1u-zzibIYHEAvuz_lu8qzulzzVD7vOjSrwcHMjI,15205
5
5
  prism_models/config.py,sha256=gy_6HknnG17Clv8X_EBhaXEBFBLGR1PLjvN5-SFTo5E,962
6
6
  prism_models/content.py,sha256=mzVZw54UiLIdWB9-A_HdjigJNNWBevmTMbGW6copXBM,10361
7
7
  prism_models/feedback.py,sha256=Z2-Fj51xGhoC2j0i6NtkbqnWzPBzJV7F7g9nB7l18I0,6702
@@ -63,8 +63,10 @@ prism_models/migration/versions/2025_11_24_1124_dc57fb290621_added_conversation_
63
63
  prism_models/migration/versions/2025_11_25_1847_c6c36663acd5_added_user_preferences_table.py,sha256=4E51jRKENB-pU2yg_Pf2zxORWFqPfHcQ4aQmblPS4Ew,2438
64
64
  prism_models/migration/versions/2025_12_07_2236_88f01df468f2_added_sparse_embeddings_field_in_vector_.py,sha256=Qrg6ouy11sESaPJcfkfh9Vk8CoOW34vrMmF69OStZDg,995
65
65
  prism_models/migration/versions/2025_12_09_1146_6abdd3f001ab_adding_orchestrator_model_to_profile_.py,sha256=eiCgTyFW7TbifwXPbZtsYW9_UPYwyCMF4I7eXnMOTwQ,937
66
- prism_models/migration/versions/2025_12_17_1220_4d9291a3acb1_removed_qa_pair_chunk.py,sha256=QnbVia8YU2_Rp0LWFvbA2lUy7kmdrGLbDmTHw-YQAoM,4752
67
- prism_models-0.6.6.dist-info/METADATA,sha256=HDaddbPooYJE6IPRyngjbuo3o5QnEwFqcrDlxhaA_Zk,283
68
- prism_models-0.6.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
69
- prism_models-0.6.6.dist-info/top_level.txt,sha256=UNzqwpLgFYU0EoyB9LiB1jTtc89A1sQ24fSEyNVvgJI,13
70
- prism_models-0.6.6.dist-info/RECORD,,
66
+ prism_models/migration/versions/2025_12_17_1220_4d9291a3acb1_removed_qa_pair_chunk.py,sha256=p0WnO1SYNqtFum15k5BwPwIWEUuGZBpEbLEtbDx-z8w,4768
67
+ prism_models/migration/versions/2026_01_14_1742_147509a82af8_changed_user_role_enums.py,sha256=S4ZSqgbCe0Xrp3Z1E10J1vg3Arh_bmCxk7YP1g67eDQ,2000
68
+ prism_models/migration/versions/2026_01_15_1010_3b7d0b2e9f5a_add_contact_profile_table.py,sha256=5G-ZmYZGXJ4TNdZms3WDwhHKbUMVp2M94f5uBSVW-j4,2790
69
+ prism_models-0.7.3.dist-info/METADATA,sha256=Xw0NmGjf3n6i9J7GCW0H2Y7LoYMGklO5Agn2Brsb9nc,283
70
+ prism_models-0.7.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
71
+ prism_models-0.7.3.dist-info/top_level.txt,sha256=UNzqwpLgFYU0EoyB9LiB1jTtc89A1sQ24fSEyNVvgJI,13
72
+ prism_models-0.7.3.dist-info/RECORD,,