@exulu/backend 1.39.0 → 1.39.2

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.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
- # [1.39.0](https://github.com/Qventu/exulu-backend/compare/v1.38.0...v1.39.0) (2025-12-03)
1
+ ## [1.39.2](https://github.com/Qventu/exulu-backend/compare/v1.39.1...v1.39.2) (2025-12-03)
2
2
 
3
3
 
4
- ### Features
4
+ ### Bug Fixes
5
5
 
6
- * add project-scoped context retrieval and enhanced personalization ([3c52de5](https://github.com/Qventu/exulu-backend/commit/3c52de58661aa450f3bf1721f366173a894c36bc))
6
+ * image handling in chat api ([62cecf8](https://github.com/Qventu/exulu-backend/commit/62cecf889d917f956768075d02e62dd8a88961df))
@@ -0,0 +1,316 @@
1
+
2
+ ----
3
+
4
+ ### feat: add project-scoped context retrieval and enhanced personalization
5
+
6
+ Date: 2025-12-03
7
+ Author: dclaessen-exulu
8
+
9
+ This commit introduces a comprehensive project-based information retrieval
10
+ system and several enhancements to the agent and context infrastructure:
11
+
12
+ **Project Context Retrieval:**
13
+ - Add createProjectRetrievalTool for project-specific information search
14
+ across multiple contexts
15
+ - Implement project caching mechanism to optimize repeated project queries
16
+ - Support hybrid search across project items with filtering and ranking
17
+ - Enable automatic project tool injection when session has associated
18
+ project
19
+
20
+ **Enhanced Personalization:**
21
+ - Add firstname/lastname fields to user authentication for API users
22
+ - Include user information in system prompts for better personalization
23
+ - Make personalization configurable via privacy settings
24
+
25
+ **Field Processor Improvements:**
26
+ - Add generateEmbeddings configuration option to field processors
27
+ - Support onInsert trigger in addition to existing triggers
28
+ - Enable processors to run without user context for system operations
29
+ - Improve processor execution flow with better logging
30
+
31
+ **Infrastructure Enhancements:**
32
+ - Add database connection pool logging for debugging
33
+ - Improve file parts processing with better error handling
34
+ - Make convertToolsArrayToObject async to support dynamic tool generation
35
+ - Enhance storage utility to support uploads without user context
36
+ - Better handling of tool variable configs vs execution configs
37
+ - Comment out unused project_id from RBAC schema
38
+
39
+ **Context and Search Improvements:**
40
+ - Add search method directly to ExuluContext class
41
+ - Expose applyFilters and contextToTableDefinition utilities
42
+ - Support context source execution with exuluConfig parameter
43
+ - Improve error messages and reduce excessive logging
44
+
45
+ 🤖 Generated with [Claude Code](https://claude.com/claude-code)
46
+
47
+ Co-Authored-By: Claude <noreply@anthropic.com>
48
+
49
+ ----
50
+
51
+ ### feat: add document parsing for AI agent file handling with JWT secret fix
52
+
53
+ Date: 2025-11-30
54
+ Author: dclaessen-exulu
55
+
56
+ Enhance agent file processing capabilities and fix authentication:
57
+
58
+ - Add officeparser integration to extract text from document files
59
+ - Implement processFilePartsInMessages to convert file parts to
60
+ OpenAI Responses API compatible format
61
+ - Convert document files to text parts with extracted content
62
+ - Keep image files as image parts (natively supported by API)
63
+ - Add message deduplication to prevent duplicate message IDs
64
+ - Change saveChat to process messages sequentially for correct
65
+ timestamp ordering
66
+ - Fix JWT verification in getToken by converting NEXTAUTH_SECRET
67
+ to base64url format as required by jose library
68
+
69
+ This enables agents to process uploaded documents by extracting
70
+ their text content and presenting it in a format compatible with
71
+ the OpenAI Responses API.
72
+
73
+ 🤖 Generated with [Claude Code](https://claude.com/claude-code)
74
+
75
+ Co-Authored-By: Claude <noreply@anthropic.com>
76
+
77
+ ----
78
+
79
+ ### feat: add PDF preview tool and enhance agent API with cookie authentication and message persistence
80
+
81
+ Date: 2025-11-26
82
+ Author: dclaessen-exulu
83
+
84
+ Adds a new preview-pdf tool for viewing PDF documents and significantly enhances the agent
85
+ chat API to support public agents with optional authentication. Implements cookie-based session
86
+ management, message ID tracking to prevent duplicates during chat persistence, and allows
87
+ passing full message arrays for stateless interactions.
88
+
89
+ Also downgrades AI SDK from v5.0.95 to v5.0.65 for stability, adds cookie-parser dependency,
90
+ and improves context embedding generation with better metadata handling and increased timeout
91
+ limits. Enhances S3 integration with multi-bucket support via key notation [bucket:name],
92
+ improves vector search result limits, and adds better error handling for encrypted variables
93
+ and external ID lookups in context operations.
94
+
95
+ 🤖 Generated with [Claude Code](https://claude.com/claude-code)
96
+
97
+ Co-Authored-By: Claude <noreply@anthropic.com>
98
+
99
+ ----
100
+
101
+ ### fix: issue with upsert
102
+
103
+ Date: 2025-11-19
104
+ Author: dclaessen-exulu
105
+
106
+
107
+ ----
108
+
109
+ ### feat: upgrade AI SDK to v5.0.95 and add Gemini 3 Pro support with parameterized context sources
110
+
111
+ Date: 2025-11-19
112
+ Author: dclaessen-exulu
113
+
114
+ This commit introduces several enhancements to the AI capabilities and context system:
115
+
116
+ - Upgrade AI SDK from v5.0.56 to v5.0.95 with improved provider utilities
117
+ - Add @vercel/oidc dependency for enhanced authentication support
118
+ - Implement Google Vertex Gemini 3 Pro agent with 1M+ token context window
119
+ - Enhance context source configuration with parameterizable inputs
120
+ - Improve Vertex authentication documentation with detailed setup instructions
121
+ - Add support for dynamic parameters in context source definitions via GraphQL schema
122
+
123
+ The new Gemini 3 Pro agent provides very high intelligence with moderate speed,
124
+ supporting text, images, files, audio, and video inputs. Context sources can now
125
+ define parameters with names, descriptions, and default values for more flexible
126
+ data retrieval configurations.
127
+
128
+ Changes include:
129
+ - src/index.ts: Export new vertexGemini3ProAgent
130
+ - src/registry/index.ts: Register Gemini 3 Pro agent
131
+ - src/registry/classes.ts: Add params field to ExuluContextSource config
132
+ - src/registry/utils/graphql.ts: Add ContextSourceParam type and params support
133
+ - src/templates/agents/google/vertex/index.ts: Add Gemini 3 Pro agent, refactor auth docs
134
+ - types/models/context.ts: Add params field to Context interface
135
+
136
+ 🤖 Generated with [Claude Code](https://claude.com/claude-code)
137
+
138
+ Co-Authored-By: Claude <noreply@anthropic.com>
139
+
140
+ ----
141
+
142
+ ### feat: add Google Vertex AI agent support and enhance embedder configuration system
143
+
144
+ Date: 2025-11-18
145
+ Author: dclaessen-exulu
146
+
147
+ Add Google Vertex Gemini 2.5 Flash agent integration with support for
148
+ optional authentication. Implement new embedder_settings table for
149
+ context-specific embedder configuration with variable management.
150
+
151
+ Major changes:
152
+ - Add vertexGemini25FlashAgent to default agents and registry
153
+ - Implement embedder_settings schema for per-context embedder config
154
+ - Add authenticationInformation field to ExuluAgent class
155
+ - Make providerapikey optional across agent and MCP initialization
156
+ - Add config field to ExuluEmbedder with hydrateEmbedderConfig method
157
+ - Pass context ID and settings to embedder chunker and generation ops
158
+ - Update GraphQL schema to expose authenticationInformation and config
159
+ - Enhance error messages with agent name and ID for better debugging
160
+
161
+ Breaking changes:
162
+ - ChunkerOperation signature now requires config parameter
163
+ - VectorGenerateOperation signature now requires settings parameter
164
+ - convertToolsArrayToObject contexts parameter now optional
165
+
166
+ This enables agents that don't require API keys (e.g., Vertex AI with
167
+ workload identity) and allows embedders to retrieve configuration from
168
+ variables per context.
169
+
170
+ 🤖 Generated with [Claude Code](https://claude.com/claude-code)
171
+
172
+ Co-Authored-By: Claude <noreply@anthropic.com>
173
+
174
+ ----
175
+
176
+ ### fix: project tracking anthropic passthrough and timeout for worker
177
+
178
+ Date: 2025-11-17
179
+ Author: dclaessen-exulu
180
+
181
+
182
+ ----
183
+
184
+ ### feat: add MCP prompt library integration and JSON filtering enhancements
185
+
186
+ Date: 2025-11-17
187
+ Author: dclaessen-exulu
188
+
189
+ Add comprehensive prompt template management via MCP tools and enhanced JSON field filtering:
190
+
191
+ Prompt Library Features:
192
+ - Add prompt_library and prompt_favorites database schemas
193
+ - Register getListOfPromptTemplates and getPromptTemplateDetails MCP tools
194
+ - Enable agents to discover and retrieve prompt templates with usage/favorite tracking
195
+ - Support agent-specific prompt assignment via assigned_agents JSON field
196
+
197
+ GraphQL & Filtering Improvements:
198
+ - Add JSON field containment support using PostgreSQL @> operator
199
+ - Enhance filter operators to handle JSON equality and IN operations with jsonb casting
200
+ - Pass table schema context to applyFilters for type-aware query building
201
+
202
+ Bug Fixes & Refinements:
203
+ - Fix upsert validation to require id or external_id
204
+ - Add source update statistics tracking for API and job triggers
205
+ - Improve eval function result metadata structure with function_results array
206
+ - Add default scoring method fallback to average for eval runs
207
+ - Fix typo: rename eval to evaluation in bullmq decorator
208
+
209
+ Configuration:
210
+ - Add .mcp.json for exulu-mcp-server-default-coding-agent integration
211
+
212
+ 🤖 Generated with [Claude Code](https://claude.com/claude-code)
213
+
214
+ Co-Authored-By: Claude <noreply@anthropic.com>
215
+
216
+ ----
217
+
218
+ ### feat: add todo system, enhanced roles, session metadata, and scheduling support
219
+
220
+ Date: 2025-11-14
221
+ Author: dclaessen-exulu
222
+
223
+ This commit introduces several significant features and improvements to the Exulu backend:
224
+
225
+ - Implement TodoWrite and TodoRead tools for session-based task tracking
226
+ - Store todos in agent_sessions.metadata JSON field
227
+ - Add access control checks for todo operations
228
+ - Tools require authenticated session context
229
+
230
+ - Create default "admin" role with full write permissions
231
+ - Create "default" role with agent write + read-only for other resources
232
+ - Add support for "evals" and "api" permissions in role structure
233
+ - Automatically provision both roles during database initialization
234
+
235
+ - Add metadata JSON column to agent_sessions table
236
+ - Pass sessionID throughout tool execution pipeline
237
+ - Implement getSession helper for consistent session retrieval
238
+ - Enable session-aware tool execution with user context
239
+
240
+ - Add cron-like scheduling support for context data sources
241
+ - Implement queue configuration options
242
+ - Add retry logic with exponential/linear backoff strategies
243
+ - Enable automated data ingestion workflows
244
+
245
+ - Fix Redis URL construction when using authentication
246
+ - Improve handling of username/password credentials
247
+ - Better fallback values for missing environment variables
248
+
249
+ - Support config-based tool description overrides
250
+ - Pass sessionID to all tool executions
251
+ - Enable tools to access session metadata
252
+ - Improve tool configuration hydration
253
+
254
+ - Add better-auth (v1.3.34) with WebAuthn support
255
+ - Include cryptography libraries (@noble/ciphers, @noble/hashes)
256
+ - Add @simplewebauthn packages for authentication flows
257
+ - Include kysely for type-safe database queries
258
+
259
+ 🤖 Generated with [Claude Code](https://claude.com/claude-code)
260
+
261
+ Co-Authored-By: Claude <noreply@anthropic.com>
262
+
263
+ ----
264
+
265
+ ### fix: add ExuluItem as export
266
+
267
+ Date: 2025-11-11
268
+ Author: dclaessen-exulu
269
+
270
+
271
+ ----
272
+
273
+ ### feat: implement scheduled data sources for contexts
274
+
275
+ Date: 2025-11-11
276
+ Author: dclaessen-exulu
277
+
278
+ Add support for scheduled data sources within ExuluContext that automatically
279
+ fetch and ingest items at regular intervals.
280
+
281
+ Key changes:
282
+ - Introduce ExuluContextSource type with configurable cron schedules, retry
283
+ logic, and backoff strategies
284
+ - Add source execution handler in BullMQ workers to process scheduled jobs
285
+ - Create automatic job schedulers for each context source with configurable
286
+ retry attempts (default: 3) and exponential backoff (default: 2000ms)
287
+ - Rename Context.process() to processField() for clarity
288
+ - Add executeSource() method to handle source execution and item creation
289
+ - Track source metadata in BullMQ job data for job identification
290
+
291
+ Sources enable automated data ingestion workflows where external data can be
292
+ pulled into contexts on a schedule without manual intervention. Each source
293
+ execution creates items in the context and optionally schedules follow-up
294
+ processing jobs for embeddings and chunking.
295
+
296
+ 🤖 Generated with [Claude Code](https://claude.com/claude-code)
297
+
298
+ Co-Authored-By: Claude <noreply@anthropic.com>
299
+
300
+ ----
301
+
302
+ ### fix: minor exulu upgrade for redis connection
303
+
304
+ Date: 2025-11-10
305
+ Author: dclaessen-exulu
306
+
307
+
308
+ ----
309
+
310
+ ### fix: redis auth url
311
+
312
+ Date: 2025-11-10
313
+ Author: dclaessen-exulu
314
+
315
+
316
+ ----
package/dist/index.cjs CHANGED
@@ -2148,52 +2148,6 @@ function createMutations(table, agents, contexts, tools, config) {
2148
2148
  }
2149
2149
  throw new Error("Insufficient role permissions to edit this record");
2150
2150
  }
2151
- if (record.rights_mode === "projects") {
2152
- const projects = await db3.from("rbac").where({
2153
- entity: table.name.singular,
2154
- target_resource_id: id,
2155
- access_type: "Project",
2156
- rights: "write"
2157
- });
2158
- if (projects.length === 0) {
2159
- throw new Error("Entity ${table.name.singular} has its rights mode set to projects, but is not shared with any projects.");
2160
- }
2161
- const checks = await Promise.all(projects.map(async (project) => {
2162
- if (project.rights_mode === "private" && project.created_by !== user.id) {
2163
- return false;
2164
- }
2165
- if (project.rights_mode === "users") {
2166
- const rbacRecord = await db3.from("rbac").where({
2167
- entity: "project",
2168
- target_resource_id: project.id,
2169
- access_type: "User",
2170
- user_id: user.id,
2171
- rights: "write"
2172
- }).first();
2173
- if (rbacRecord) {
2174
- return true;
2175
- }
2176
- return false;
2177
- }
2178
- if (record.rights_mode === "roles" && user.role) {
2179
- const rbacRecord = await db3.from("rbac").where({
2180
- entity: "project",
2181
- target_resource_id: project.id,
2182
- access_type: "Role",
2183
- role_id: user.role,
2184
- rights: "write"
2185
- }).first();
2186
- if (rbacRecord) {
2187
- return true;
2188
- }
2189
- return false;
2190
- }
2191
- return false;
2192
- }));
2193
- if (checks.some((check) => check)) {
2194
- return true;
2195
- }
2196
- }
2197
2151
  throw new Error("Insufficient permissions to edit this record");
2198
2152
  } catch (error) {
2199
2153
  console.error("Write access validation error:", error);
@@ -3442,16 +3396,14 @@ var RBACResolver = async (db3, entityName, resourceId, rights_mode) => {
3442
3396
  }).select("*");
3443
3397
  const users = rbacRecords.filter((r) => r.access_type === "User")?.map((r) => ({ id: r.user_id, rights: r.rights }));
3444
3398
  const roles = rbacRecords.filter((r) => r.access_type === "Role")?.map((r) => ({ id: r.role_id, rights: r.rights }));
3445
- const projects = rbacRecords.filter((r) => r.access_type === "Project")?.map((r) => ({ id: r.project_id, rights: r.rights }));
3446
3399
  let type = rights_mode || "private";
3447
3400
  if (type === "users" && users.length === 0) type = "private";
3448
3401
  if (type === "roles" && roles.length === 0) type = "private";
3449
- if (type === "projects" && projects.length === 0) type = "private";
3450
3402
  return {
3451
3403
  type,
3452
3404
  users,
3453
- roles,
3454
- projects
3405
+ roles
3406
+ // projects
3455
3407
  };
3456
3408
  };
3457
3409
  var contextToTableDefinition = (context) => {
@@ -3555,7 +3507,7 @@ function createSDL(tables, contexts, agents, tools, config, evals, queues2) {
3555
3507
  type: String!
3556
3508
  users: [RBACUser!]
3557
3509
  roles: [RBACRole!]
3558
- projects: [RBACProject!]
3510
+
3559
3511
  }
3560
3512
 
3561
3513
  type RBACUser {
@@ -3568,15 +3520,9 @@ function createSDL(tables, contexts, agents, tools, config, evals, queues2) {
3568
3520
  rights: String!
3569
3521
  }
3570
3522
 
3571
- type RBACProject {
3572
- id: ID!
3573
- rights: String!
3574
- }
3575
-
3576
3523
  input RBACInput {
3577
3524
  users: [RBACUserInput!]
3578
3525
  roles: [RBACRoleInput!]
3579
- projects: [RBACProjectInput!]
3580
3526
  }
3581
3527
 
3582
3528
  input RBACUserInput {
@@ -3589,11 +3535,6 @@ function createSDL(tables, contexts, agents, tools, config, evals, queues2) {
3589
3535
  rights: String!
3590
3536
  }
3591
3537
 
3592
- input RBACProjectInput {
3593
- id: ID!
3594
- rights: String!
3595
- }
3596
-
3597
3538
  type Query {
3598
3539
  `;
3599
3540
  let mutationDefs = `
@@ -5671,14 +5612,19 @@ var ExuluAgent2 = class {
5671
5612
  if (part.type !== "file") {
5672
5613
  return part;
5673
5614
  }
5615
+ console.log(`[EXULU] Processing part`, part);
5674
5616
  const { mediaType, url, filename } = part;
5675
- const imageTypes = ["image/png", "image/jpeg", "image/jpg", "image/gif", "image/webp"];
5676
- if (imageTypes.includes(mediaType)) {
5617
+ console.log(`[EXULU] Media type: ${mediaType}`);
5618
+ console.log(`[EXULU] URL: ${url}`);
5619
+ console.log(`[EXULU] Filename: ${filename}`);
5620
+ const imageTypes = [".png", ".jpeg", ".jpg", ".gif", ".webp"];
5621
+ const imageType = imageTypes.find((type) => filename.toLowerCase().includes(type.toLowerCase()));
5622
+ if (imageType) {
5677
5623
  console.log(`[EXULU] Converting file part to image part: ${filename} `);
5678
5624
  return {
5679
- type: "image",
5680
- image: url,
5681
- mimeType: mediaType
5625
+ type: "file",
5626
+ mediaType: `image/${imageType.replace(".", "")}`,
5627
+ url
5682
5628
  };
5683
5629
  }
5684
5630
  console.log(`[EXULU] Converting file part to text using officeparser: ${filename}`);
package/dist/index.d.cts CHANGED
@@ -202,7 +202,7 @@ interface Agent {
202
202
  audio: audioTypes$1[];
203
203
  video: videoTypes$1[];
204
204
  };
205
- rights_mode?: 'private' | 'users' | 'roles' | 'public' | 'projects';
205
+ rights_mode?: 'private' | 'users' | 'roles' | 'public';
206
206
  created_by?: string;
207
207
  RBAC?: {
208
208
  type?: string;
@@ -214,10 +214,6 @@ interface Agent {
214
214
  id: string;
215
215
  rights: 'read' | 'write';
216
216
  }>;
217
- projects?: Array<{
218
- id: string;
219
- rights: 'read' | 'write';
220
- }>;
221
217
  };
222
218
  createdAt?: string;
223
219
  updatedAt?: string;
@@ -573,7 +569,7 @@ type ExuluContextFieldDefinition = {
573
569
  allowedFileTypes?: allFileTypes[];
574
570
  processor?: ExuluContextFieldProcessor;
575
571
  };
576
- type ExuluRightsMode = "private" | "users" | "roles" | "public" | "projects";
572
+ type ExuluRightsMode = "private" | "users" | "roles" | "public";
577
573
  declare class ExuluStorage {
578
574
  private config;
579
575
  constructor({ config }: {
package/dist/index.d.ts CHANGED
@@ -202,7 +202,7 @@ interface Agent {
202
202
  audio: audioTypes$1[];
203
203
  video: videoTypes$1[];
204
204
  };
205
- rights_mode?: 'private' | 'users' | 'roles' | 'public' | 'projects';
205
+ rights_mode?: 'private' | 'users' | 'roles' | 'public';
206
206
  created_by?: string;
207
207
  RBAC?: {
208
208
  type?: string;
@@ -214,10 +214,6 @@ interface Agent {
214
214
  id: string;
215
215
  rights: 'read' | 'write';
216
216
  }>;
217
- projects?: Array<{
218
- id: string;
219
- rights: 'read' | 'write';
220
- }>;
221
217
  };
222
218
  createdAt?: string;
223
219
  updatedAt?: string;
@@ -573,7 +569,7 @@ type ExuluContextFieldDefinition = {
573
569
  allowedFileTypes?: allFileTypes[];
574
570
  processor?: ExuluContextFieldProcessor;
575
571
  };
576
- type ExuluRightsMode = "private" | "users" | "roles" | "public" | "projects";
572
+ type ExuluRightsMode = "private" | "users" | "roles" | "public";
577
573
  declare class ExuluStorage {
578
574
  private config;
579
575
  constructor({ config }: {
package/dist/index.js CHANGED
@@ -2096,52 +2096,6 @@ function createMutations(table, agents, contexts, tools, config) {
2096
2096
  }
2097
2097
  throw new Error("Insufficient role permissions to edit this record");
2098
2098
  }
2099
- if (record.rights_mode === "projects") {
2100
- const projects = await db3.from("rbac").where({
2101
- entity: table.name.singular,
2102
- target_resource_id: id,
2103
- access_type: "Project",
2104
- rights: "write"
2105
- });
2106
- if (projects.length === 0) {
2107
- throw new Error("Entity ${table.name.singular} has its rights mode set to projects, but is not shared with any projects.");
2108
- }
2109
- const checks = await Promise.all(projects.map(async (project) => {
2110
- if (project.rights_mode === "private" && project.created_by !== user.id) {
2111
- return false;
2112
- }
2113
- if (project.rights_mode === "users") {
2114
- const rbacRecord = await db3.from("rbac").where({
2115
- entity: "project",
2116
- target_resource_id: project.id,
2117
- access_type: "User",
2118
- user_id: user.id,
2119
- rights: "write"
2120
- }).first();
2121
- if (rbacRecord) {
2122
- return true;
2123
- }
2124
- return false;
2125
- }
2126
- if (record.rights_mode === "roles" && user.role) {
2127
- const rbacRecord = await db3.from("rbac").where({
2128
- entity: "project",
2129
- target_resource_id: project.id,
2130
- access_type: "Role",
2131
- role_id: user.role,
2132
- rights: "write"
2133
- }).first();
2134
- if (rbacRecord) {
2135
- return true;
2136
- }
2137
- return false;
2138
- }
2139
- return false;
2140
- }));
2141
- if (checks.some((check) => check)) {
2142
- return true;
2143
- }
2144
- }
2145
2099
  throw new Error("Insufficient permissions to edit this record");
2146
2100
  } catch (error) {
2147
2101
  console.error("Write access validation error:", error);
@@ -3390,16 +3344,14 @@ var RBACResolver = async (db3, entityName, resourceId, rights_mode) => {
3390
3344
  }).select("*");
3391
3345
  const users = rbacRecords.filter((r) => r.access_type === "User")?.map((r) => ({ id: r.user_id, rights: r.rights }));
3392
3346
  const roles = rbacRecords.filter((r) => r.access_type === "Role")?.map((r) => ({ id: r.role_id, rights: r.rights }));
3393
- const projects = rbacRecords.filter((r) => r.access_type === "Project")?.map((r) => ({ id: r.project_id, rights: r.rights }));
3394
3347
  let type = rights_mode || "private";
3395
3348
  if (type === "users" && users.length === 0) type = "private";
3396
3349
  if (type === "roles" && roles.length === 0) type = "private";
3397
- if (type === "projects" && projects.length === 0) type = "private";
3398
3350
  return {
3399
3351
  type,
3400
3352
  users,
3401
- roles,
3402
- projects
3353
+ roles
3354
+ // projects
3403
3355
  };
3404
3356
  };
3405
3357
  var contextToTableDefinition = (context) => {
@@ -3503,7 +3455,7 @@ function createSDL(tables, contexts, agents, tools, config, evals, queues2) {
3503
3455
  type: String!
3504
3456
  users: [RBACUser!]
3505
3457
  roles: [RBACRole!]
3506
- projects: [RBACProject!]
3458
+
3507
3459
  }
3508
3460
 
3509
3461
  type RBACUser {
@@ -3516,15 +3468,9 @@ function createSDL(tables, contexts, agents, tools, config, evals, queues2) {
3516
3468
  rights: String!
3517
3469
  }
3518
3470
 
3519
- type RBACProject {
3520
- id: ID!
3521
- rights: String!
3522
- }
3523
-
3524
3471
  input RBACInput {
3525
3472
  users: [RBACUserInput!]
3526
3473
  roles: [RBACRoleInput!]
3527
- projects: [RBACProjectInput!]
3528
3474
  }
3529
3475
 
3530
3476
  input RBACUserInput {
@@ -3537,11 +3483,6 @@ function createSDL(tables, contexts, agents, tools, config, evals, queues2) {
3537
3483
  rights: String!
3538
3484
  }
3539
3485
 
3540
- input RBACProjectInput {
3541
- id: ID!
3542
- rights: String!
3543
- }
3544
-
3545
3486
  type Query {
3546
3487
  `;
3547
3488
  let mutationDefs = `
@@ -5638,14 +5579,19 @@ var ExuluAgent2 = class {
5638
5579
  if (part.type !== "file") {
5639
5580
  return part;
5640
5581
  }
5582
+ console.log(`[EXULU] Processing part`, part);
5641
5583
  const { mediaType, url, filename } = part;
5642
- const imageTypes = ["image/png", "image/jpeg", "image/jpg", "image/gif", "image/webp"];
5643
- if (imageTypes.includes(mediaType)) {
5584
+ console.log(`[EXULU] Media type: ${mediaType}`);
5585
+ console.log(`[EXULU] URL: ${url}`);
5586
+ console.log(`[EXULU] Filename: ${filename}`);
5587
+ const imageTypes = [".png", ".jpeg", ".jpg", ".gif", ".webp"];
5588
+ const imageType = imageTypes.find((type) => filename.toLowerCase().includes(type.toLowerCase()));
5589
+ if (imageType) {
5644
5590
  console.log(`[EXULU] Converting file part to image part: ${filename} `);
5645
5591
  return {
5646
- type: "image",
5647
- image: url,
5648
- mimeType: mediaType
5592
+ type: "file",
5593
+ mediaType: `image/${imageType.replace(".", "")}`,
5594
+ url
5649
5595
  };
5650
5596
  }
5651
5597
  console.log(`[EXULU] Converting file part to text using officeparser: ${filename}`);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@exulu/backend",
3
3
  "author": "Qventu Bv.",
4
- "version": "1.39.0",
4
+ "version": "1.39.2",
5
5
  "main": "./dist/index.js",
6
6
  "private": false,
7
7
  "publishConfig": {
@@ -8,12 +8,12 @@ export interface AgentSession {
8
8
  project: string;
9
9
  title: string;
10
10
  created_by: string;
11
- rights_mode: 'private' | 'users' | 'roles' | 'public' | 'projects'
11
+ rights_mode: 'private' | 'users' | 'roles' | 'public' /* | 'projects' */
12
12
  RBAC?: {
13
13
  type?: string;
14
14
  users?: Array<{ id: string; rights: 'read' | 'write' }>;
15
15
  roles?: Array<{ id: string; rights: 'read' | 'write' }>;
16
- projects?: Array<{ id: string; rights: 'read' | 'write' }>;
16
+ /* projects?: Array<{ id: string; rights: 'read' | 'write' }>; */
17
17
  };
18
18
  }
19
19
  export interface AgentMessage {
@@ -41,13 +41,13 @@ export interface Agent {
41
41
  video: videoTypes[];
42
42
  }
43
43
  // New RBAC fields
44
- rights_mode?: 'private' | 'users' | 'roles' | 'public' | 'projects';
44
+ rights_mode?: 'private' | 'users' | 'roles' | 'public' /* | 'projects' */;
45
45
  created_by?: string;
46
46
  RBAC?: {
47
47
  type?: string;
48
48
  users?: Array<{ id: number; rights: 'read' | 'write' }>;
49
49
  roles?: Array<{ id: string; rights: 'read' | 'write' }>;
50
- projects?: Array<{ id: string; rights: 'read' | 'write' }>;
50
+ /* projects?: Array<{ id: string; rights: 'read' | 'write' }>; */
51
51
  };
52
52
  createdAt?: string;
53
53
  updatedAt?: string;
@@ -17,12 +17,12 @@ export interface EvalRun {
17
17
  scoring_method: ScoringMethod
18
18
  pass_threshold: number // 0-100 percentage
19
19
  test_case_ids: string[] // Subset of test cases from the eval set
20
- rights_mode: "private" | "users" | "roles" | "projects" | "public"
20
+ rights_mode: "private" | "users" | "roles" |/* "projects" | */"public"
21
21
  RBAC?: {
22
22
  type?: string
23
23
  users?: Array<{ id: number; rights: "read" | "write" }>
24
24
  roles?: Array<{ id: string; rights: "read" | "write" }>
25
- projects?: Array<{ id: string; rights: "read" | "write" }>
25
+ // projects?: Array<{ id: string; rights: "read" | "write" }>
26
26
  }
27
27
  createdAt: string
28
28
  updatedAt: string