@iblai/iblai-api 4.388.0-ai → 4.389.0-ai

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.
Files changed (106) hide show
  1. package/dist/index.cjs.js +2 -2
  2. package/dist/index.esm.js +2 -2
  3. package/dist/index.umd.js +2 -2
  4. package/dist/types/models/AIGeneratedImage.d.ts +7 -0
  5. package/dist/types/models/Artifact.d.ts +2 -0
  6. package/dist/types/models/ArtifactList.d.ts +2 -0
  7. package/dist/types/models/ChatHistoryFilterUser.d.ts +1 -0
  8. package/dist/types/models/ChatRunTracker.d.ts +8 -0
  9. package/dist/types/models/ConnectedService.d.ts +2 -0
  10. package/dist/types/models/ConversationMessage.d.ts +1 -0
  11. package/dist/types/models/Conversations.d.ts +1 -0
  12. package/dist/types/models/CourseCreationTask.d.ts +2 -0
  13. package/dist/types/models/Dataset.d.ts +1 -0
  14. package/dist/types/models/DisclaimerAgreement.d.ts +2 -0
  15. package/dist/types/models/ElevenlabsCustomVoiceResponse.d.ts +2 -0
  16. package/dist/types/models/Entity.d.ts +2 -0
  17. package/dist/types/models/HostingProject.d.ts +2 -0
  18. package/dist/types/models/JudgeRecord.d.ts +1 -0
  19. package/dist/types/models/MCPServer.d.ts +2 -0
  20. package/dist/types/models/MCPServerConnection.d.ts +2 -0
  21. package/dist/types/models/MemoryComponentMemoryDetail.d.ts +2 -0
  22. package/dist/types/models/MemoryStatusView.d.ts +28 -0
  23. package/dist/types/models/MentorAuditLogEntry.d.ts +4 -0
  24. package/dist/types/models/ModerationLog.d.ts +10 -1
  25. package/dist/types/models/NestedArtifact.d.ts +2 -0
  26. package/dist/types/models/PatchedArtifact.d.ts +2 -0
  27. package/dist/types/models/PatchedConversations.d.ts +1 -0
  28. package/dist/types/models/PatchedMCPServer.d.ts +2 -0
  29. package/dist/types/models/PatchedMCPServerConnection.d.ts +2 -0
  30. package/dist/types/models/PatchedPeriodicAgentCreate.d.ts +28 -0
  31. package/dist/types/models/PatchedProject.d.ts +2 -0
  32. package/dist/types/models/PatchedWorkflow.d.ts +2 -0
  33. package/dist/types/models/PeriodicAgent.d.ts +28 -0
  34. package/dist/types/models/PeriodicAgentCreate.d.ts +28 -0
  35. package/dist/types/models/Project.d.ts +2 -0
  36. package/dist/types/models/RetrieverDocumentEmbedding.d.ts +8 -0
  37. package/dist/types/models/Run.d.ts +1 -0
  38. package/dist/types/models/RunDetailResponse.d.ts +1 -0
  39. package/dist/types/models/Score.d.ts +1 -0
  40. package/dist/types/models/ScoreCreateResponse.d.ts +1 -0
  41. package/dist/types/models/SpendCap.d.ts +4 -2
  42. package/dist/types/models/StarMentor.d.ts +2 -0
  43. package/dist/types/models/StudentChatMessage.d.ts +5 -0
  44. package/dist/types/models/UserAllChatMemoryView.d.ts +28 -0
  45. package/dist/types/models/UserCatalogItemMemoryView.d.ts +2 -0
  46. package/dist/types/models/UserChatFeedback.d.ts +9 -0
  47. package/dist/types/models/UserChatMemoryStatusView.d.ts +28 -0
  48. package/dist/types/models/UserDefaultMentor.d.ts +2 -0
  49. package/dist/types/models/UserEdxMemory.d.ts +2 -0
  50. package/dist/types/models/UserMemoryContextResponse.d.ts +28 -0
  51. package/dist/types/models/VersionNestedArtifact.d.ts +2 -0
  52. package/dist/types/models/Workflow.d.ts +2 -0
  53. package/dist/types/services/AiMentorService.d.ts +1 -1
  54. package/package.json +1 -1
  55. package/sdk_schema.yml +645 -4
  56. package/src/core/OpenAPI.ts +1 -1
  57. package/src/models/AIGeneratedImage.ts +7 -0
  58. package/src/models/Artifact.ts +2 -0
  59. package/src/models/ArtifactList.ts +2 -0
  60. package/src/models/ChatHistoryFilterUser.ts +1 -0
  61. package/src/models/ChatRunTracker.ts +8 -0
  62. package/src/models/ConnectedService.ts +2 -0
  63. package/src/models/ConversationMessage.ts +1 -0
  64. package/src/models/Conversations.ts +1 -0
  65. package/src/models/CourseCreationTask.ts +2 -0
  66. package/src/models/Dataset.ts +1 -0
  67. package/src/models/DisclaimerAgreement.ts +2 -0
  68. package/src/models/ElevenlabsCustomVoiceResponse.ts +2 -0
  69. package/src/models/Entity.ts +2 -0
  70. package/src/models/HostingProject.ts +2 -0
  71. package/src/models/JudgeRecord.ts +1 -0
  72. package/src/models/MCPServer.ts +2 -0
  73. package/src/models/MCPServerConnection.ts +2 -0
  74. package/src/models/MemoryComponentMemoryDetail.ts +2 -0
  75. package/src/models/MemoryStatusView.ts +28 -0
  76. package/src/models/MentorAuditLogEntry.ts +4 -0
  77. package/src/models/ModerationLog.ts +10 -1
  78. package/src/models/NestedArtifact.ts +2 -0
  79. package/src/models/PatchedArtifact.ts +2 -0
  80. package/src/models/PatchedConversations.ts +1 -0
  81. package/src/models/PatchedMCPServer.ts +2 -0
  82. package/src/models/PatchedMCPServerConnection.ts +2 -0
  83. package/src/models/PatchedPeriodicAgentCreate.ts +28 -0
  84. package/src/models/PatchedProject.ts +2 -0
  85. package/src/models/PatchedWorkflow.ts +2 -0
  86. package/src/models/PeriodicAgent.ts +28 -0
  87. package/src/models/PeriodicAgentCreate.ts +28 -0
  88. package/src/models/Project.ts +2 -0
  89. package/src/models/RetrieverDocumentEmbedding.ts +8 -0
  90. package/src/models/Run.ts +1 -0
  91. package/src/models/RunDetailResponse.ts +1 -0
  92. package/src/models/Score.ts +1 -0
  93. package/src/models/ScoreCreateResponse.ts +1 -0
  94. package/src/models/SpendCap.ts +4 -2
  95. package/src/models/StarMentor.ts +2 -0
  96. package/src/models/StudentChatMessage.ts +5 -0
  97. package/src/models/UserAllChatMemoryView.ts +28 -0
  98. package/src/models/UserCatalogItemMemoryView.ts +2 -0
  99. package/src/models/UserChatFeedback.ts +9 -0
  100. package/src/models/UserChatMemoryStatusView.ts +28 -0
  101. package/src/models/UserDefaultMentor.ts +2 -0
  102. package/src/models/UserEdxMemory.ts +2 -0
  103. package/src/models/UserMemoryContextResponse.ts +28 -0
  104. package/src/models/VersionNestedArtifact.ts +2 -0
  105. package/src/models/Workflow.ts +2 -0
  106. package/src/services/AiMentorService.ts +1 -1
package/dist/index.cjs.js CHANGED
@@ -110,7 +110,7 @@ class CancelablePromise {
110
110
 
111
111
  const OpenAPI = {
112
112
  BASE: 'https://base.manager.iblai.app',
113
- VERSION: '4.388.0-ai-plus',
113
+ VERSION: '4.389.0-ai-plus',
114
114
  WITH_CREDENTIALS: false,
115
115
  CREDENTIALS: 'include',
116
116
  TOKEN: undefined,
@@ -20583,7 +20583,7 @@ class AiMentorService{/**
20583
20583
  * Retrieve experiment run details
20584
20584
  * Returns the run header plus every `dataset_run_item` fully expanded with `input`, `expected_output`, `actual_output`, `trace_id`, and per-item `scores`. Also embeds a `pending_judges` array for any in-flight LLM-as-Judge evaluations against this run.
20585
20585
  *
20586
- * Cost: 1 PG query + 2 ClickHouse queries + 1 score query regardless of run size.
20586
+ * Cost: 1 PG query + 2 ClickHouse queries + 1 score query + 1 identity query, all flat regardless of run size.
20587
20587
  * @returns RunDetailResponse
20588
20588
  * @throws ApiError
20589
20589
  */static aiMentorOrgsUsersEvaluationsDatasetsRunsRetrieve({datasetName,org,runName,userId}){return request(OpenAPI,{method:'GET',url:'/api/ai-mentor/orgs/{org}/users/{user_id}/evaluations/datasets/{dataset_name}/runs/{run_name}/',path:{'dataset_name':datasetName,'org':org,'run_name':runName,'user_id':userId},errors:{403:`Authenticated, but the resource belongs to another tenant.`,404:`Not found within the tenant.`}});}/**
package/dist/index.esm.js CHANGED
@@ -108,7 +108,7 @@ class CancelablePromise {
108
108
 
109
109
  const OpenAPI = {
110
110
  BASE: 'https://base.manager.iblai.app',
111
- VERSION: '4.388.0-ai-plus',
111
+ VERSION: '4.389.0-ai-plus',
112
112
  WITH_CREDENTIALS: false,
113
113
  CREDENTIALS: 'include',
114
114
  TOKEN: undefined,
@@ -20581,7 +20581,7 @@ class AiMentorService{/**
20581
20581
  * Retrieve experiment run details
20582
20582
  * Returns the run header plus every `dataset_run_item` fully expanded with `input`, `expected_output`, `actual_output`, `trace_id`, and per-item `scores`. Also embeds a `pending_judges` array for any in-flight LLM-as-Judge evaluations against this run.
20583
20583
  *
20584
- * Cost: 1 PG query + 2 ClickHouse queries + 1 score query regardless of run size.
20584
+ * Cost: 1 PG query + 2 ClickHouse queries + 1 score query + 1 identity query, all flat regardless of run size.
20585
20585
  * @returns RunDetailResponse
20586
20586
  * @throws ApiError
20587
20587
  */static aiMentorOrgsUsersEvaluationsDatasetsRunsRetrieve({datasetName,org,runName,userId}){return request(OpenAPI,{method:'GET',url:'/api/ai-mentor/orgs/{org}/users/{user_id}/evaluations/datasets/{dataset_name}/runs/{run_name}/',path:{'dataset_name':datasetName,'org':org,'run_name':runName,'user_id':userId},errors:{403:`Authenticated, but the resource belongs to another tenant.`,404:`Not found within the tenant.`}});}/**
package/dist/index.umd.js CHANGED
@@ -114,7 +114,7 @@
114
114
 
115
115
  const OpenAPI = {
116
116
  BASE: 'https://base.manager.iblai.app',
117
- VERSION: '4.388.0-ai-plus',
117
+ VERSION: '4.389.0-ai-plus',
118
118
  WITH_CREDENTIALS: false,
119
119
  CREDENTIALS: 'include',
120
120
  TOKEN: undefined,
@@ -20587,7 +20587,7 @@
20587
20587
  * Retrieve experiment run details
20588
20588
  * Returns the run header plus every `dataset_run_item` fully expanded with `input`, `expected_output`, `actual_output`, `trace_id`, and per-item `scores`. Also embeds a `pending_judges` array for any in-flight LLM-as-Judge evaluations against this run.
20589
20589
  *
20590
- * Cost: 1 PG query + 2 ClickHouse queries + 1 score query regardless of run size.
20590
+ * Cost: 1 PG query + 2 ClickHouse queries + 1 score query + 1 identity query, all flat regardless of run size.
20591
20591
  * @returns RunDetailResponse
20592
20592
  * @throws ApiError
20593
20593
  */static aiMentorOrgsUsersEvaluationsDatasetsRunsRetrieve({datasetName,org,runName,userId}){return request(OpenAPI,{method:'GET',url:'/api/ai-mentor/orgs/{org}/users/{user_id}/evaluations/datasets/{dataset_name}/runs/{run_name}/',path:{'dataset_name':datasetName,'org':org,'run_name':runName,'user_id':userId},errors:{403:`Authenticated, but the resource belongs to another tenant.`,404:`Not found within the tenant.`}});}/**
@@ -1,9 +1,16 @@
1
+ /**
2
+ * A generated image. ``user`` is the numeric id, so the identity fields
3
+ * let a client render the owner without a second request.
4
+ */
1
5
  export type AIGeneratedImage = {
2
6
  readonly id: number;
3
7
  /**
4
8
  * edX user ID
5
9
  */
6
10
  user?: number | null;
11
+ readonly username: string | null;
12
+ readonly user_email: string | null;
13
+ readonly user_full_name: string | null;
7
14
  image: string;
8
15
  platform?: number | null;
9
16
  prompt?: string;
@@ -60,6 +60,8 @@ export type Artifact = {
60
60
  * Username of the student who owns this artifact
61
61
  */
62
62
  readonly username: string;
63
+ readonly user_email: string | null;
64
+ readonly user_full_name: string | null;
63
65
  readonly session_id: string | null;
64
66
  /**
65
67
  * Version number of the current version
@@ -42,6 +42,8 @@ export type ArtifactList = {
42
42
  * Username of the student who owns this artifact
43
43
  */
44
44
  readonly username: string;
45
+ readonly user_email: string | null;
46
+ readonly user_full_name: string | null;
45
47
  readonly session_id: string | null;
46
48
  /**
47
49
  * Length of the artifact content in characters (bytes for binary artifacts)
@@ -1,5 +1,6 @@
1
1
  export type ChatHistoryFilterUser = {
2
2
  username: string;
3
3
  email: string;
4
+ readonly user_full_name: string | null;
4
5
  readonly lti_email: string;
5
6
  };
@@ -1,12 +1,20 @@
1
1
  import type { ChatRunTrackerStatusEnum } from './ChatRunTrackerStatusEnum';
2
2
  import type { FailureCategoryEnum } from './FailureCategoryEnum';
3
3
  import type { ModalityEnum } from './ModalityEnum';
4
+ /**
5
+ * A single chat run.
6
+ *
7
+ * ``username`` and ``email`` are denormalized onto the row at write time;
8
+ * only the display name needs resolving, so the mixin's ``user_email`` twin
9
+ * is dropped in favour of the existing column.
10
+ */
4
11
  export type ChatRunTracker = {
5
12
  readonly id: string;
6
13
  readonly session_id: string;
7
14
  readonly mentor_unique_id: string;
8
15
  readonly username: string;
9
16
  readonly email: string;
17
+ readonly user_full_name: string | null;
10
18
  readonly platform_key: string;
11
19
  readonly generation_id: string;
12
20
  readonly modality: ModalityEnum;
@@ -25,4 +25,6 @@ export type ConnectedService = {
25
25
  * Return the username strings associated with the connection.
26
26
  */
27
27
  readonly username: Array<string>;
28
+ readonly user_email: string | null;
29
+ readonly user_full_name: string | null;
28
30
  };
@@ -5,6 +5,7 @@ export type ConversationMessage = {
5
5
  id: string;
6
6
  user_id: string;
7
7
  email: string | null;
8
+ readonly user_full_name: string | null;
8
9
  readonly message_count: number;
9
10
  model: string;
10
11
  inserted_at: string;
@@ -7,6 +7,7 @@ export type Conversations = {
7
7
  mentor: string;
8
8
  readonly student: string;
9
9
  readonly email: string;
10
+ readonly user_full_name: string | null;
10
11
  model: string;
11
12
  readonly rating: number;
12
13
  platform: string;
@@ -3,6 +3,8 @@ import type { CourseCreationTaskStatusEnum } from './CourseCreationTaskStatusEnu
3
3
  export type CourseCreationTask = {
4
4
  readonly id: number;
5
5
  readonly user_id: string;
6
+ readonly user_email: string | null;
7
+ readonly user_full_name: string | null;
6
8
  /**
7
9
  * edX user ID
8
10
  */
@@ -9,4 +9,5 @@ export type Dataset = {
9
9
  updated_at: string;
10
10
  readonly username: string;
11
11
  readonly user_email: string;
12
+ readonly user_full_name: string;
12
13
  };
@@ -8,4 +8,6 @@ export type DisclaimerAgreement = {
8
8
  readonly agreed_at: string;
9
9
  readonly platform_key: string;
10
10
  readonly user_id: string;
11
+ readonly user_email: string | null;
12
+ readonly user_full_name: string | null;
11
13
  };
@@ -1,6 +1,8 @@
1
1
  export type ElevenlabsCustomVoiceResponse = {
2
2
  name: string;
3
3
  readonly owner_student: string | null;
4
+ readonly owner_email: string | null;
5
+ readonly owner_full_name: string | null;
4
6
  language?: string;
5
7
  is_premade?: boolean;
6
8
  description?: string;
@@ -5,6 +5,8 @@ import type { EntityTypeEnum } from './EntityTypeEnum';
5
5
  export type Entity = {
6
6
  type?: EntityTypeEnum;
7
7
  username?: string;
8
+ user_email?: string | null;
9
+ user_full_name?: string | null;
8
10
  platform_key?: string;
9
11
  platform_name?: string;
10
12
  display_name: string;
@@ -27,6 +27,8 @@ export type HostingProject = {
27
27
  readonly push_state: string;
28
28
  readonly push_error: string;
29
29
  readonly username: string;
30
+ readonly user_email: string | null;
31
+ readonly user_full_name: string | null;
30
32
  readonly created_at: string;
31
33
  readonly updated_at: string;
32
34
  };
@@ -12,6 +12,7 @@ export type JudgeRecord = {
12
12
  error_message: string;
13
13
  readonly username: string;
14
14
  readonly user_email: string;
15
+ readonly user_full_name: string;
15
16
  created_at: string;
16
17
  started_at?: string | null;
17
18
  completed_at?: string | null;
@@ -13,6 +13,8 @@ export type MCPServer = {
13
13
  * edX username
14
14
  */
15
15
  owner?: string | null;
16
+ readonly owner_email: string | null;
17
+ readonly owner_full_name: string | null;
16
18
  name: string;
17
19
  /**
18
20
  * A description of the MCP server.
@@ -26,6 +26,8 @@ export type MCPServerConnection = {
26
26
  * edX username
27
27
  */
28
28
  user?: string | null;
29
+ readonly user_email: string | null;
30
+ readonly user_full_name: string | null;
29
31
  mentor?: string | null;
30
32
  connected_service?: number | null;
31
33
  readonly connected_service_summary: Record<string, any> | null;
@@ -4,5 +4,7 @@ export type MemoryComponentMemoryDetail = {
4
4
  readonly catalog_item: string;
5
5
  readonly mentor_unique_id: string;
6
6
  readonly student: string;
7
+ readonly student_email: string | null;
8
+ readonly student_full_name: string | null;
7
9
  readonly inserted_at: string;
8
10
  };
@@ -1,6 +1,34 @@
1
+ /**
2
+ * Adds read-only ``user_email``/``user_full_name`` from a username column.
3
+ *
4
+ * For models that store the username but hold no FK to the user, so there is
5
+ * nothing to traverse. Resolution costs **one query per payload**: DRF reuses
6
+ * a single child serializer for a whole page, so the first field access reads
7
+ * every username being serialized and looks them all up at once. A view that
8
+ * already knows the identities can put a ``user_identity_map`` in serializer
9
+ * context to skip the query entirely.
10
+ *
11
+ * ``SerializerMetaclass`` is what collects ``_declared_fields``; it also keeps
12
+ * this out of the MRO games that subclassing ``Serializer`` into a
13
+ * ``ModelSerializer`` would introduce.
14
+ *
15
+ * **Privacy invariant — resolve only from the row's own stored username.**
16
+ * Chat privacy's ``ANONYMIZED`` mode removes identity by writing the row with
17
+ * no username (``ibl_ai_langchain_ext/langchain/memories.py``:
18
+ * ``None if privacy_mode == ChatPrivacyMode.ANONYMIZED else self.username``),
19
+ * so an anonymised row reaches this mixin with nothing to look up and renders
20
+ * nulls. That is the whole of the protection: nothing here may back-fill the
21
+ * identity from elsewhere (``session.student``, the request user, …), or an
22
+ * anonymised row would be re-identified in the response. Privacy mode redacts
23
+ * conversation *text*, not identity, on the other rows this mixin serves —
24
+ * a moderation log or run tracker keeps its username by design — so those
25
+ * resolving an identity is intended, not a leak.
26
+ */
1
27
  export type MemoryStatusView = {
2
28
  readonly id: number;
3
29
  username: string;
30
+ readonly user_email: string | null;
31
+ readonly user_full_name: string | null;
4
32
  platform_key: string;
5
33
  enabled?: boolean;
6
34
  };
@@ -20,6 +20,10 @@ export type MentorAuditLogEntry = {
20
20
  * Email of the user who performed the action
21
21
  */
22
22
  actor_email: string | null;
23
+ /**
24
+ * Display name of the user who performed the action
25
+ */
26
+ actor_full_name: string | null;
23
27
  /**
24
28
  * Action type: create, update, or delete
25
29
  */
@@ -1,8 +1,17 @@
1
1
  import type { TargetSystemEnum } from './TargetSystemEnum';
2
+ /**
3
+ * A moderation/safety log row.
4
+ *
5
+ * ``ModerationLog`` denormalizes only ``username``, so the email and name
6
+ * come from the mixin — one query per page, and a row whose user has since
7
+ * been deleted reports nulls instead of raising. ``email`` keeps its
8
+ * established name, so the mixin's ``user_email`` twin is dropped.
9
+ */
2
10
  export type ModerationLog = {
3
11
  readonly id: number;
4
12
  username?: string;
5
- readonly email: string;
13
+ readonly email: string | null;
14
+ readonly user_full_name: string | null;
6
15
  platform_key: string;
7
16
  mentor: number;
8
17
  prompt: string;
@@ -43,6 +43,8 @@ export type NestedArtifact = {
43
43
  * Username of the student who owns this artifact
44
44
  */
45
45
  readonly username: string;
46
+ readonly user_email: string | null;
47
+ readonly user_full_name: string | null;
46
48
  readonly session_id: string | null;
47
49
  /**
48
50
  * Version number of the current version
@@ -60,6 +60,8 @@ export type PatchedArtifact = {
60
60
  * Username of the student who owns this artifact
61
61
  */
62
62
  readonly username?: string;
63
+ readonly user_email?: string | null;
64
+ readonly user_full_name?: string | null;
63
65
  readonly session_id?: string | null;
64
66
  /**
65
67
  * Version number of the current version
@@ -7,6 +7,7 @@ export type PatchedConversations = {
7
7
  mentor?: string;
8
8
  readonly student?: string;
9
9
  readonly email?: string;
10
+ readonly user_full_name?: string | null;
10
11
  model?: string;
11
12
  readonly rating?: number;
12
13
  platform?: string;
@@ -13,6 +13,8 @@ export type PatchedMCPServer = {
13
13
  * edX username
14
14
  */
15
15
  owner?: string | null;
16
+ readonly owner_email?: string | null;
17
+ readonly owner_full_name?: string | null;
16
18
  name?: string;
17
19
  /**
18
20
  * A description of the MCP server.
@@ -26,6 +26,8 @@ export type PatchedMCPServerConnection = {
26
26
  * edX username
27
27
  */
28
28
  user?: string | null;
29
+ readonly user_email?: string | null;
30
+ readonly user_full_name?: string | null;
29
31
  mentor?: string | null;
30
32
  connected_service?: number | null;
31
33
  readonly connected_service_summary?: Record<string, any> | null;
@@ -1,10 +1,38 @@
1
1
  import type { PeriodicTask } from './PeriodicTask';
2
2
  import type { PreviousAgentStatusEnum } from './PreviousAgentStatusEnum';
3
+ /**
4
+ * Adds read-only ``user_email``/``user_full_name`` from a username column.
5
+ *
6
+ * For models that store the username but hold no FK to the user, so there is
7
+ * nothing to traverse. Resolution costs **one query per payload**: DRF reuses
8
+ * a single child serializer for a whole page, so the first field access reads
9
+ * every username being serialized and looks them all up at once. A view that
10
+ * already knows the identities can put a ``user_identity_map`` in serializer
11
+ * context to skip the query entirely.
12
+ *
13
+ * ``SerializerMetaclass`` is what collects ``_declared_fields``; it also keeps
14
+ * this out of the MRO games that subclassing ``Serializer`` into a
15
+ * ``ModelSerializer`` would introduce.
16
+ *
17
+ * **Privacy invariant — resolve only from the row's own stored username.**
18
+ * Chat privacy's ``ANONYMIZED`` mode removes identity by writing the row with
19
+ * no username (``ibl_ai_langchain_ext/langchain/memories.py``:
20
+ * ``None if privacy_mode == ChatPrivacyMode.ANONYMIZED else self.username``),
21
+ * so an anonymised row reaches this mixin with nothing to look up and renders
22
+ * nulls. That is the whole of the protection: nothing here may back-fill the
23
+ * identity from elsewhere (``session.student``, the request user, …), or an
24
+ * anonymised row would be re-identified in the response. Privacy mode redacts
25
+ * conversation *text*, not identity, on the other rows this mixin serves —
26
+ * a moderation log or run tracker keeps its username by design — so those
27
+ * resolving an identity is intended, not a leak.
28
+ */
3
29
  export type PatchedPeriodicAgentCreate = {
4
30
  readonly id?: number;
5
31
  mentor?: string;
6
32
  title?: string;
7
33
  readonly username?: string;
34
+ readonly user_email?: string | null;
35
+ readonly user_full_name?: string | null;
8
36
  description?: string;
9
37
  /**
10
38
  * Prompt for the periodic agent if any.
@@ -29,6 +29,8 @@ export type PatchedProject = {
29
29
  */
30
30
  readonly owner?: number;
31
31
  readonly owner_username?: string;
32
+ readonly owner_email?: string | null;
33
+ readonly owner_full_name?: string | null;
32
34
  /**
33
35
  * Platform this project belongs to
34
36
  */
@@ -36,6 +36,8 @@ export type PatchedWorkflow = {
36
36
  */
37
37
  readonly created_by?: number;
38
38
  readonly created_by_username?: string;
39
+ readonly created_by_email?: string | null;
40
+ readonly created_by_full_name?: string | null;
39
41
  readonly created_at?: string;
40
42
  readonly updated_at?: string;
41
43
  /**
@@ -1,11 +1,39 @@
1
1
  import type { Mentor } from './Mentor';
2
2
  import type { PeriodicTask } from './PeriodicTask';
3
3
  import type { PreviousAgentStatusEnum } from './PreviousAgentStatusEnum';
4
+ /**
5
+ * Adds read-only ``user_email``/``user_full_name`` from a username column.
6
+ *
7
+ * For models that store the username but hold no FK to the user, so there is
8
+ * nothing to traverse. Resolution costs **one query per payload**: DRF reuses
9
+ * a single child serializer for a whole page, so the first field access reads
10
+ * every username being serialized and looks them all up at once. A view that
11
+ * already knows the identities can put a ``user_identity_map`` in serializer
12
+ * context to skip the query entirely.
13
+ *
14
+ * ``SerializerMetaclass`` is what collects ``_declared_fields``; it also keeps
15
+ * this out of the MRO games that subclassing ``Serializer`` into a
16
+ * ``ModelSerializer`` would introduce.
17
+ *
18
+ * **Privacy invariant — resolve only from the row's own stored username.**
19
+ * Chat privacy's ``ANONYMIZED`` mode removes identity by writing the row with
20
+ * no username (``ibl_ai_langchain_ext/langchain/memories.py``:
21
+ * ``None if privacy_mode == ChatPrivacyMode.ANONYMIZED else self.username``),
22
+ * so an anonymised row reaches this mixin with nothing to look up and renders
23
+ * nulls. That is the whole of the protection: nothing here may back-fill the
24
+ * identity from elsewhere (``session.student``, the request user, …), or an
25
+ * anonymised row would be re-identified in the response. Privacy mode redacts
26
+ * conversation *text*, not identity, on the other rows this mixin serves —
27
+ * a moderation log or run tracker keeps its username by design — so those
28
+ * resolving an identity is intended, not a leak.
29
+ */
4
30
  export type PeriodicAgent = {
5
31
  readonly id: number;
6
32
  mentor: Mentor;
7
33
  title: string;
8
34
  readonly username: string;
35
+ readonly user_email: string | null;
36
+ readonly user_full_name: string | null;
9
37
  description?: string;
10
38
  /**
11
39
  * Prompt for the periodic agent if any.
@@ -1,10 +1,38 @@
1
1
  import type { PeriodicTask } from './PeriodicTask';
2
2
  import type { PreviousAgentStatusEnum } from './PreviousAgentStatusEnum';
3
+ /**
4
+ * Adds read-only ``user_email``/``user_full_name`` from a username column.
5
+ *
6
+ * For models that store the username but hold no FK to the user, so there is
7
+ * nothing to traverse. Resolution costs **one query per payload**: DRF reuses
8
+ * a single child serializer for a whole page, so the first field access reads
9
+ * every username being serialized and looks them all up at once. A view that
10
+ * already knows the identities can put a ``user_identity_map`` in serializer
11
+ * context to skip the query entirely.
12
+ *
13
+ * ``SerializerMetaclass`` is what collects ``_declared_fields``; it also keeps
14
+ * this out of the MRO games that subclassing ``Serializer`` into a
15
+ * ``ModelSerializer`` would introduce.
16
+ *
17
+ * **Privacy invariant — resolve only from the row's own stored username.**
18
+ * Chat privacy's ``ANONYMIZED`` mode removes identity by writing the row with
19
+ * no username (``ibl_ai_langchain_ext/langchain/memories.py``:
20
+ * ``None if privacy_mode == ChatPrivacyMode.ANONYMIZED else self.username``),
21
+ * so an anonymised row reaches this mixin with nothing to look up and renders
22
+ * nulls. That is the whole of the protection: nothing here may back-fill the
23
+ * identity from elsewhere (``session.student``, the request user, …), or an
24
+ * anonymised row would be re-identified in the response. Privacy mode redacts
25
+ * conversation *text*, not identity, on the other rows this mixin serves —
26
+ * a moderation log or run tracker keeps its username by design — so those
27
+ * resolving an identity is intended, not a leak.
28
+ */
3
29
  export type PeriodicAgentCreate = {
4
30
  readonly id: number;
5
31
  mentor: string;
6
32
  title: string;
7
33
  readonly username: string;
34
+ readonly user_email: string | null;
35
+ readonly user_full_name: string | null;
8
36
  description?: string;
9
37
  /**
10
38
  * Prompt for the periodic agent if any.
@@ -29,6 +29,8 @@ export type Project = {
29
29
  */
30
30
  readonly owner: number;
31
31
  readonly owner_username: string;
32
+ readonly owner_email: string | null;
33
+ readonly owner_full_name: string | null;
32
34
  /**
33
35
  * Platform this project belongs to
34
36
  */
@@ -3,12 +3,20 @@ import type { BlankEnum } from './BlankEnum';
3
3
  import type { CrawlerPatternTypeEnum } from './CrawlerPatternTypeEnum';
4
4
  import type { NullEnum } from './NullEnum';
5
5
  import type { TrainingStatusEnum } from './TrainingStatusEnum';
6
+ /**
7
+ * A trained document.
8
+ *
9
+ * ``DocumentEmbedding`` denormalizes ``username`` and holds no FK to the
10
+ * user, so the email and name are resolved by the mixin — one query per page.
11
+ */
6
12
  export type RetrieverDocumentEmbedding = {
7
13
  readonly id: number;
8
14
  metadata?: any;
9
15
  document_name?: string | null;
10
16
  document_type?: string | null;
11
17
  username: string;
18
+ readonly user_email: string | null;
19
+ readonly user_full_name: string | null;
12
20
  training_status?: (TrainingStatusEnum | BlankEnum | NullEnum) | null;
13
21
  pathway: string;
14
22
  url?: string | null;
@@ -16,6 +16,7 @@ export type Run = {
16
16
  status: string;
17
17
  readonly username: string;
18
18
  readonly user_email: string;
19
+ readonly user_full_name: string;
19
20
  task_id?: string;
20
21
  task_record_id?: number | null;
21
22
  };
@@ -12,6 +12,7 @@ export type RunDetailResponse = {
12
12
  status: string;
13
13
  readonly username: string;
14
14
  readonly user_email: string;
15
+ readonly user_full_name: string;
15
16
  task_id?: string;
16
17
  task_record_id?: number | null;
17
18
  dataset_run_items: Array<DatasetRunItem>;
@@ -14,4 +14,5 @@ export type Score = {
14
14
  created_at: string;
15
15
  readonly username: string;
16
16
  readonly user_email: string;
17
+ readonly user_full_name: string;
17
18
  };
@@ -5,4 +5,5 @@ export type ScoreCreateResponse = {
5
5
  value: number;
6
6
  username: string;
7
7
  user_email: string;
8
+ readonly user_full_name: string;
8
9
  };
@@ -9,8 +9,9 @@ import type { SpendCapScopeEnum } from './SpendCapScopeEnum';
9
9
  * (``current_spend_usd``/``remaining_usd``/``is_exceeded``) are reconciled
10
10
  * from ClickHouse and surfaced read-only so a UI can render a progress bar.
11
11
  * ``scope``/``platform``/``mentor``/``user`` are set by the view, never the
12
- * request body; ``mentor_unique_id``/``username`` are echoed read-only so the
13
- * caller can tell which agent/user a cap belongs to.
12
+ * request body; ``mentor_unique_id``/``username``/``email``/``user_full_name``
13
+ * are echoed read-only so the caller can tell which agent/user a cap belongs
14
+ * to and render it without a second request.
14
15
  */
15
16
  export type SpendCap = {
16
17
  readonly id: number;
@@ -20,6 +21,7 @@ export type SpendCap = {
20
21
  readonly mentor_name: string | null;
21
22
  readonly username: string | null;
22
23
  readonly email: string | null;
24
+ readonly user_full_name: string | null;
23
25
  interval_type: IntervalTypeEnum;
24
26
  max_cost_usd: string;
25
27
  enforcement?: EnforcementEnum;
@@ -3,6 +3,8 @@ export type StarMentor = {
3
3
  readonly updated_at: string;
4
4
  readonly mentor: string;
5
5
  readonly student: string;
6
+ readonly student_email: string | null;
7
+ readonly student_full_name: string | null;
6
8
  readonly recently_accessed_at: string | null;
7
9
  readonly id: number;
8
10
  readonly unique_id: string;
@@ -1,4 +1,9 @@
1
+ /**
2
+ * Message counts aggregated per user; the rows are dicts.
3
+ */
1
4
  export type StudentChatMessage = {
5
+ readonly user_email: string | null;
6
+ readonly user_full_name: string | null;
2
7
  username: string;
3
8
  chat_message_count: number;
4
9
  };
@@ -1,6 +1,34 @@
1
+ /**
2
+ * Adds read-only ``user_email``/``user_full_name`` from a username column.
3
+ *
4
+ * For models that store the username but hold no FK to the user, so there is
5
+ * nothing to traverse. Resolution costs **one query per payload**: DRF reuses
6
+ * a single child serializer for a whole page, so the first field access reads
7
+ * every username being serialized and looks them all up at once. A view that
8
+ * already knows the identities can put a ``user_identity_map`` in serializer
9
+ * context to skip the query entirely.
10
+ *
11
+ * ``SerializerMetaclass`` is what collects ``_declared_fields``; it also keeps
12
+ * this out of the MRO games that subclassing ``Serializer`` into a
13
+ * ``ModelSerializer`` would introduce.
14
+ *
15
+ * **Privacy invariant — resolve only from the row's own stored username.**
16
+ * Chat privacy's ``ANONYMIZED`` mode removes identity by writing the row with
17
+ * no username (``ibl_ai_langchain_ext/langchain/memories.py``:
18
+ * ``None if privacy_mode == ChatPrivacyMode.ANONYMIZED else self.username``),
19
+ * so an anonymised row reaches this mixin with nothing to look up and renders
20
+ * nulls. That is the whole of the protection: nothing here may back-fill the
21
+ * identity from elsewhere (``session.student``, the request user, …), or an
22
+ * anonymised row would be re-identified in the response. Privacy mode redacts
23
+ * conversation *text*, not identity, on the other rows this mixin serves —
24
+ * a moderation log or run tracker keeps its username by design — so those
25
+ * resolving an identity is intended, not a leak.
26
+ */
1
27
  export type UserAllChatMemoryView = {
2
28
  readonly id: number;
3
29
  username: string;
30
+ readonly user_email: string | null;
31
+ readonly user_full_name: string | null;
4
32
  platform_key: string;
5
33
  content?: string | null;
6
34
  session_id?: string | null;