Skip to content

Commit 2b2be17

Browse files
authored
Merge pull request #1270 from refly-ai/main
Release v0.10.0
2 parents 6c13768 + 5156663 commit 2b2be17

File tree

220 files changed

+9144
-4176
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

220 files changed

+9144
-4176
lines changed

apps/api/prisma/schema.prisma

Lines changed: 50 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,8 @@ model PilotStep {
253253
status String @default("init") @map("status")
254254
/// Raw step output from LLM
255255
rawOutput String? @map("raw_output")
256+
/// Divergent node fields
257+
mode String? @default("subtask") @map("mode")
256258
/// Create timestamp
257259
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz()
258260
/// Update timestamp
@@ -271,25 +273,29 @@ enum ActionStatus {
271273

272274
model TokenUsage {
273275
/// Primary key
274-
pk BigInt @id @default(autoincrement())
276+
pk BigInt @id @default(autoincrement())
275277
/// UID
276-
uid String @map("uid")
278+
uid String @map("uid")
277279
/// Action result id
278-
resultId String? @map("result_id")
280+
resultId String? @map("result_id")
279281
/// Model tier
280-
tier String @map("tier")
282+
tier String @map("tier")
281283
/// Model provider
282-
modelProvider String @default("") @map("model_provider")
284+
modelProvider String @default("") @map("model_provider")
283285
/// Model name
284-
modelName String @default("") @map("model_name")
286+
modelName String @default("") @map("model_name")
287+
/// Model label
288+
modelLabel String @default("") @map("model_label")
289+
/// Provider item id
290+
providerItemId String? @map("provider_item_id")
285291
/// Input tokens
286-
inputTokens Int @default(0) @map("input_tokens")
292+
inputTokens Int @default(0) @map("input_tokens")
287293
/// Output tokens
288-
outputTokens Int @default(0) @map("output_tokens")
294+
outputTokens Int @default(0) @map("output_tokens")
289295
/// Create timestamp
290-
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz()
296+
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz()
291297
/// Update timestamp
292-
updatedAt DateTime @default(now()) @updatedAt @map("updated_at") @db.Timestamptz()
298+
updatedAt DateTime @default(now()) @updatedAt @map("updated_at") @db.Timestamptz()
293299
294300
@@index([uid, createdAt])
295301
@@map("token_usages")
@@ -330,37 +336,40 @@ model StaticFile {
330336

331337
model Canvas {
332338
/// Primary key
333-
pk BigInt @id @default(autoincrement())
339+
pk BigInt @id @default(autoincrement())
334340
/// Canvas id
335-
canvasId String @unique @map("canvas_id")
341+
canvasId String @unique @map("canvas_id")
336342
/// Owner UID
337-
uid String @map("uid")
343+
uid String @map("uid")
338344
/// Canvas title
339-
title String @default("Untitled") @map("title")
345+
title String @default("Untitled") @map("title")
340346
/// Canvas yjs doc storage size (in bytes)
341-
storageSize BigInt @default(0) @map("storage_size")
347+
storageSize BigInt @default(0) @map("storage_size")
342348
/// Canvas version
343-
version String @default("") @map("version")
349+
version String @default("") @map("version")
344350
/// Canvas yjs doc storage key (deprecated, use `dataStorageKey` instead)
345-
stateStorageKey String? @map("state_storage_key")
351+
stateStorageKey String? @map("state_storage_key")
346352
/// Minimap storage key
347-
minimapStorageKey String? @map("minimap_storage_key")
353+
minimapStorageKey String? @map("minimap_storage_key")
348354
/// Whether this canvas is readonly
349-
readOnly Boolean @default(false) @map("read_only")
355+
readOnly Boolean @default(false) @map("read_only")
350356
/// Whether this canvas is public
351-
isPublic Boolean @default(false) @map("is_public")
357+
isPublic Boolean @default(false) @map("is_public")
352358
/// Canvas status
353-
status String @default("ready") @map("status")
359+
status String @default("ready") @map("status")
354360
/// Create timestamp
355-
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz()
361+
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz()
356362
/// Update timestamp
357-
updatedAt DateTime @default(now()) @updatedAt @map("updated_at") @db.Timestamptz()
363+
updatedAt DateTime @default(now()) @updatedAt @map("updated_at") @db.Timestamptz()
358364
/// Soft delete timestamp
359-
deletedAt DateTime? @map("deleted_at") @db.Timestamptz()
365+
deletedAt DateTime? @map("deleted_at") @db.Timestamptz()
360366
/// Project id
361-
projectId String? @map("project_id")
367+
projectId String? @map("project_id")
362368
/// Project
363-
project Project? @relation(fields: [projectId], references: [projectId])
369+
project Project? @relation(fields: [projectId], references: [projectId])
370+
Resource Resource[]
371+
Document Document[]
372+
CodeArtifact CodeArtifact[]
364373
365374
@@index([uid, updatedAt])
366375
@@map("canvases")
@@ -510,6 +519,10 @@ model Resource {
510519
wordCount Int @default(0) @map("word_count")
511520
/// Content preview
512521
contentPreview String? @map("content_preview")
522+
/// Canvas id
523+
canvasId String? @map("canvas_id")
524+
/// Canvas
525+
canvas Canvas? @relation(fields: [canvasId], references: [canvasId])
513526
/// Content storage key
514527
storageKey String? @map("storage_key")
515528
/// Content storage size (in bytes)
@@ -572,6 +585,10 @@ model Document {
572585
updatedAt DateTime @default(now()) @updatedAt @map("updated_at") @db.Timestamptz()
573586
/// Soft delete timestamp
574587
deletedAt DateTime? @map("deleted_at") @db.Timestamptz()
588+
/// Canvas id
589+
canvasId String? @map("canvas_id")
590+
/// Canvas
591+
canvas Canvas? @relation(fields: [canvasId], references: [canvasId])
575592
/// Project id
576593
projectId String? @map("project_id")
577594
/// Project
@@ -602,6 +619,10 @@ model CodeArtifact {
602619
resultId String? @map("result_id")
603620
/// Action result version
604621
resultVersion Int @default(0) @map("result_version")
622+
/// Canvas id
623+
canvasId String? @map("canvas_id")
624+
/// Canvas
625+
canvas Canvas? @relation(fields: [canvasId], references: [canvasId])
605626
/// Create timestamp
606627
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz()
607628
/// Update timestamp
@@ -926,6 +947,8 @@ model ProviderItem {
926947
order Int @default(0) @map("order")
927948
/// Group name
928949
groupName String @default("") @map("group_name")
950+
/// Related global provider item ID
951+
globalItemId String? @map("global_item_id")
929952
/// Create timestamp
930953
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz()
931954
/// Update timestamp
@@ -937,6 +960,7 @@ model ProviderItem {
937960
938961
@@index([providerId])
939962
@@index([uid, deletedAt])
963+
@@index([globalItemId])
940964
@@map("provider_items")
941965
}
942966

apps/api/src/main.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,23 @@ async function bootstrap() {
3636
rawBody: true,
3737
bufferLogs: false,
3838
});
39-
app.useLogger(app.get(Logger));
39+
const logger = app.get(Logger);
40+
app.useLogger(logger);
4041

4142
const configService = app.get(ConfigService);
4243

4344
process.on('uncaughtException', (err) => {
45+
const stack = (err as Error)?.stack ?? String(err);
46+
logger.error(`main process uncaughtException: ${stack}`);
4447
Sentry.captureException(err);
48+
// Do not exit; keep the process alive. Investigate recurring errors via Sentry logs.
4549
});
4650

4751
process.on('unhandledRejection', (err) => {
48-
Sentry.captureException(err);
52+
const message = (err as Error)?.stack ?? String(err);
53+
logger.error(`main process unhandledRejection: ${message}`);
54+
Sentry.captureException(err as any);
55+
// Do not exit; keep the process alive. Investigate recurring errors via Sentry logs.
4956
});
5057

5158
app.useBodyParser('json', { limit: '10mb' });

apps/api/src/modules/action/action.service.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,14 @@ export class ActionService {
3939
throw new ActionResultNotFoundError();
4040
}
4141

42-
const item = await this.providerService.findLLMProviderItemByModelID(user, result.modelName);
42+
const item =
43+
(result.providerItemId
44+
? await this.providerService.findProviderItemById(user, result.providerItemId)
45+
: null) ||
46+
(result.modelName
47+
? (await this.providerService.findLLMProviderItemByModelID(user, result.modelName)) ||
48+
(await this.providerService.findMediaProviderItemByModelID(user, result.modelName))
49+
: null);
4350
const modelInfo = item ? providerItem2ModelInfo(item) : null;
4451

4552
const steps = await this.prisma.actionStep.findMany({

apps/api/src/modules/app.module.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,6 @@ class CustomThrottlerGuard extends ThrottlerGuard {
7070
},
7171
autoLogging: false,
7272
genReqId: () => api.trace.getSpan(api.context.active())?.spanContext()?.traceId,
73-
customSuccessObject: (req) => ({
74-
env: process.env.NODE_ENV,
75-
uid: (req as any).user?.uid || 'anonymous',
76-
}),
7773
transport: process.env.NODE_ENV !== 'production' ? { target: 'pino-pretty' } : undefined,
7874
formatters: {
7975
level: (level) => ({ level }),

apps/api/src/modules/canvas/canvas-sync.service.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
CanvasConflictException,
2323
purgeContextItems,
2424
calculateCanvasStateDiff,
25+
shouldCreateNewVersion,
2526
} from '@refly/canvas-common';
2627
import {
2728
CanvasNotFoundError,
@@ -380,6 +381,20 @@ export class CanvasSyncService {
380381
throw new CanvasNotFoundError();
381382
}
382383

384+
// If no need to create new version, return the current state
385+
if (!shouldCreateNewVersion(state)) {
386+
this.logger.log(
387+
`[createCanvasVersion] no need to create version for canvas ${canvasId}, current version: ${canvas.version}`,
388+
);
389+
return {
390+
canvasId,
391+
newState: state,
392+
};
393+
}
394+
395+
this.logger.log(
396+
`[createCanvasVersion] create version for canvas ${canvasId}, current version: ${canvas.version}`,
397+
);
383398
const releaseLock = await this.lockState(canvasId);
384399

385400
try {
@@ -443,6 +458,10 @@ export class CanvasSyncService {
443458
createdAt: Date.now(),
444459
updatedAt: Date.now(),
445460
};
461+
this.logger.log(
462+
`[createCanvasVersion] create version for canvas ${canvasId}, new version: ${newState.version}`,
463+
);
464+
446465
const stateStorageKey = await this.saveState(canvasId, newState);
447466

448467
await this.prisma.$transaction([

apps/api/src/modules/canvas/canvas.service.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ export class CanvasService {
194194
const doc = await this.knowledgeService.duplicateDocument(user, {
195195
docId: entityId,
196196
title: node.data?.title,
197+
canvasId: newCanvasId,
197198
});
198199
if (doc) {
199200
node.data.entityId = doc.docId;
@@ -205,6 +206,7 @@ export class CanvasService {
205206
const resource = await this.knowledgeService.duplicateResource(user, {
206207
resourceId: entityId,
207208
title: node.data?.title,
209+
canvasId: newCanvasId,
208210
});
209211
if (resource) {
210212
node.data.entityId = resource.resourceId;
@@ -213,10 +215,10 @@ export class CanvasService {
213215
break;
214216
}
215217
case 'codeArtifact': {
216-
const codeArtifact = await this.codeArtifactService.duplicateCodeArtifact(
217-
user,
218-
entityId,
219-
);
218+
const codeArtifact = await this.codeArtifactService.duplicateCodeArtifact(user, {
219+
artifactId: entityId,
220+
canvasId: newCanvasId,
221+
});
220222
if (codeArtifact) {
221223
node.data.entityId = codeArtifact.artifactId;
222224
replaceEntityMap[entityId] = codeArtifact.artifactId;
@@ -357,24 +359,27 @@ export class CanvasService {
357359
* @param canvasId - The id of the canvas to add the node to
358360
* @param node - The node to add
359361
* @param connectTo - The nodes to connect to
362+
* @param options - Additional options including autoLayout
360363
*/
361364
async addNodeToCanvas(
362365
user: User,
363366
canvasId: string,
364367
node: Pick<CanvasNode, 'type' | 'data'>,
365368
connectTo?: CanvasNodeFilter[],
369+
options?: { autoLayout?: boolean },
366370
) {
367371
const releaseLock = await this.canvasSyncService.lockState(canvasId);
368372
const { nodes, edges } = await this.canvasSyncService.getCanvasData(user, { canvasId });
369373

370374
this.logger.log(
371-
`[addNodeToCanvas] add node to canvas ${canvasId}, node: ${JSON.stringify(node)}, nodes: ${JSON.stringify(nodes)}, edges: ${JSON.stringify(edges)}`,
375+
`[addNodeToCanvas] add node to canvas ${canvasId}, node: ${JSON.stringify(node)}, autoLayout: ${options?.autoLayout}`,
372376
);
373377
const { newNode, newEdges } = prepareAddNode({
374378
node,
375379
nodes,
376380
edges,
377381
connectTo,
382+
autoLayout: options?.autoLayout, // Pass autoLayout parameter
378383
});
379384

380385
await this.canvasSyncService.syncState(
@@ -834,8 +839,7 @@ export class CanvasService {
834839
user,
835840
'titleGeneration',
836841
);
837-
const modelConfig = JSON.parse(defaultModel.config);
838-
const model = await this.providerService.prepareChatModel(user, modelConfig.modelId);
842+
const model = await this.providerService.prepareChatModel(user, defaultModel.itemId);
839843
this.logger.log(`Using default model for auto naming: ${model.name}`);
840844

841845
// Use the new structured title generation approach

0 commit comments

Comments
 (0)