@nocobase/app-plugin-agents 2.0.0-beta.4 → 2.0.0-beta.6

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 (88) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +10 -0
  3. package/dist/client/chat/api.d.ts +6 -1
  4. package/dist/client/chat/api.d.ts.map +1 -1
  5. package/dist/client/chat/api.js +18 -0
  6. package/dist/client/chat/api.js.map +1 -1
  7. package/dist/client/chat/controller.d.ts.map +1 -1
  8. package/dist/client/chat/controller.js +2 -0
  9. package/dist/client/chat/controller.js.map +1 -1
  10. package/dist/client/components/route-child-page.d.ts +1 -1
  11. package/dist/client/components/route-child-page.d.ts.map +1 -1
  12. package/dist/client/components/route-child-page.js +18 -2
  13. package/dist/client/components/route-child-page.js.map +1 -1
  14. package/dist/client/components/route-overlay.d.ts +4 -1
  15. package/dist/client/components/route-overlay.d.ts.map +1 -1
  16. package/dist/client/components/route-overlay.js +32 -3
  17. package/dist/client/components/route-overlay.js.map +1 -1
  18. package/dist/client/components/unsaved-changes.d.ts.map +1 -1
  19. package/dist/client/components/unsaved-changes.js +17 -4
  20. package/dist/client/components/unsaved-changes.js.map +1 -1
  21. package/dist/client/components/use-route-overlay.d.ts +2 -9
  22. package/dist/client/components/use-route-overlay.d.ts.map +1 -1
  23. package/dist/client/components/use-route-overlay.js +5 -3
  24. package/dist/client/components/use-route-overlay.js.map +1 -1
  25. package/dist/client/routes.d.ts.map +1 -1
  26. package/dist/client/routes.js +7 -0
  27. package/dist/client/routes.js.map +1 -1
  28. package/dist/database/migrations/.manifest.json +4 -0
  29. package/dist/database/migrations/202611080001_ag_conversation_shares.d.ts +4 -0
  30. package/dist/database/migrations/202611080001_ag_conversation_shares.d.ts.map +1 -0
  31. package/dist/database/migrations/202611080001_ag_conversation_shares.js +25 -0
  32. package/dist/database/migrations/202611080001_ag_conversation_shares.js.map +1 -0
  33. package/dist/package.json +1 -1
  34. package/dist/server/composition.d.ts.map +1 -1
  35. package/dist/server/composition.js +1 -0
  36. package/dist/server/composition.js.map +1 -1
  37. package/dist/server/core/conversations/attachments.d.ts +0 -11
  38. package/dist/server/core/conversations/attachments.d.ts.map +1 -1
  39. package/dist/server/core/conversations/attachments.js +25 -5
  40. package/dist/server/core/conversations/attachments.js.map +1 -1
  41. package/dist/server/core/conversations/conversation.service.d.ts +2 -0
  42. package/dist/server/core/conversations/conversation.service.d.ts.map +1 -1
  43. package/dist/server/core/conversations/conversation.service.js +130 -1
  44. package/dist/server/core/conversations/conversation.service.js.map +1 -1
  45. package/dist/server/core/conversations/index.d.ts +1 -0
  46. package/dist/server/core/conversations/index.d.ts.map +1 -1
  47. package/dist/server/core/conversations/links.d.ts.map +1 -1
  48. package/dist/server/core/conversations/links.js +10 -5
  49. package/dist/server/core/conversations/links.js.map +1 -1
  50. package/dist/server/core/conversations/ports.d.ts +6 -0
  51. package/dist/server/core/conversations/ports.d.ts.map +1 -1
  52. package/dist/server/core/conversations/shares.d.ts +38 -0
  53. package/dist/server/core/conversations/shares.d.ts.map +1 -0
  54. package/dist/server/core/conversations/shares.js +189 -0
  55. package/dist/server/core/conversations/shares.js.map +1 -0
  56. package/dist/server/core/runs/claim.d.ts.map +1 -1
  57. package/dist/server/core/runs/claim.js +1 -0
  58. package/dist/server/core/runs/claim.js.map +1 -1
  59. package/dist/server/core/runs/ports.d.ts +2 -0
  60. package/dist/server/core/runs/ports.d.ts.map +1 -1
  61. package/dist/server/core/runs/ports.js.map +1 -1
  62. package/dist/server/core/runs/run.service.d.ts +7 -0
  63. package/dist/server/core/runs/run.service.d.ts.map +1 -1
  64. package/dist/server/core/runs/run.service.js +2 -1
  65. package/dist/server/core/runs/run.service.js.map +1 -1
  66. package/dist/server/core/runs/run.store.d.ts +12 -0
  67. package/dist/server/core/runs/run.store.d.ts.map +1 -1
  68. package/dist/server/core/runs/run.store.js +30 -0
  69. package/dist/server/core/runs/run.store.js.map +1 -1
  70. package/dist/server/online/agent/persistence/store.d.ts.map +1 -1
  71. package/dist/server/online/agent/persistence/store.js +3 -0
  72. package/dist/server/online/agent/persistence/store.js.map +1 -1
  73. package/dist/server/online/agent/runner/projection.d.ts +1 -1
  74. package/dist/server/online/agent/runner/projection.d.ts.map +1 -1
  75. package/dist/server/online/agent/runner/projection.js +8 -1
  76. package/dist/server/online/agent/runner/projection.js.map +1 -1
  77. package/dist/server/routes/chat.d.ts.map +1 -1
  78. package/dist/server/routes/chat.js +91 -11
  79. package/dist/server/routes/chat.js.map +1 -1
  80. package/dist/server/routes/schemas.d.ts.map +1 -1
  81. package/dist/server/routes/schemas.js +6 -1
  82. package/dist/server/routes/schemas.js.map +1 -1
  83. package/dist/shared/conversations.d.ts +17 -0
  84. package/dist/shared/conversations.d.ts.map +1 -1
  85. package/dist/shared/conversations.js.map +1 -1
  86. package/docs/conversation-sharing.md +55 -0
  87. package/package.json +3 -3
  88. package/skills/nocobase-app-plugin-agents/references/extension-points.md +2 -0
@@ -12,6 +12,8 @@ import { type ConversationRecord } from './conversation.store.js';
12
12
  import type { ConversationService } from './ports.js';
13
13
  import type { AppUIMessage } from '../../../shared/online-agent.js';
14
14
  export interface ConversationServiceDeps {
15
+ /** Reuse the native backend's registered public tool projections, without an executable session facade. */
16
+ readonly nativeHistory?: (messages: unknown[]) => Promise<AppUIMessage[]>;
15
17
  readonly nativeNotice?: (unit: Tx, record: ConversationRecord, id: string, parts: AppUIMessage['parts']) => Promise<unknown>;
16
18
  readonly tx: TxRunner;
17
19
  readonly measure?: (phase: string, durationMs: number) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.service.d.ts","sourceRoot":"","sources":["../../../../server/core/conversations/conversation.service.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,mBAAmB,CAAC;AA+D3B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAQnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,KAAK,YAAY,EAAa,MAAM,oBAAoB,CAAC;AAElE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAQL,KAAK,gBAAgB,EACrB,KAAK,UAAU,EAGhB,MAAM,kBAAkB,CAAC;AAS1B,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAYL,KAAK,kBAAkB,EAGxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAIV,mBAAmB,EAGpB,MAAM,YAAY,CAAC;AAapB,OAAO,KAAK,EAAE,YAAY,EAAa,MAAM,iCAAiC,CAAC;AAK/E,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,YAAY,CAAC,EAAE,CACtB,IAAI,EAAE,EAAE,EACR,MAAM,EAAE,kBAAkB,EAC1B,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,KACzB,OAAO,CAAC,OAAO,CAAC,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/D,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,WAAW,GAAG,KAAK,GAAG,MAAM,CAAC,CAAC;IAClE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC;IACtD,QAAQ,CAAC,WAAW,EAAE,IAAI,CACxB,gBAAgB,EAChB,UAAU,GAAG,YAAY,GAAG,SAAS,CACtC,CAAC;IACF,QAAQ,CAAC,IAAI,EAAE,IAAI,CACjB,UAAU,EACV,SAAS,GAAG,QAAQ,GAAG,gBAAgB,GAAG,KAAK,GAAG,QAAQ,GAAG,WAAW,CACzE,CAAC;IACF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;IACvC,QAAQ,CAAC,YAAY,EAAE,gBAAgB,CAAC;IACxC,iEAAiE;IACjE,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAClD,6FAA6F;IAC7F,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;IACrD,4EAA4E;IAC5E,QAAQ,CAAC,YAAY,CAAC,EAAE,CACtB,SAAS,EAAE,MAAM,EACjB,gBAAgB,CAAC,EAAE,OAAO,KACvB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC,+FAA+F;IAC/F,QAAQ,CAAC,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAC3C,kFAAkF;IAClF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,MAAM,CAAC;CAClC;AA6LD,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,uBAAuB,GAC5B,mBAAmB,CAkhFrB"}
1
+ {"version":3,"file":"conversation.service.d.ts","sourceRoot":"","sources":["../../../../server/core/conversations/conversation.service.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,7 @@
1
+ import { conversationAccess, createConversationShares, sharesRepo, } from './shares.js';
2
+ import { runnerUIPage } from '../../online/agent/runner/projection.js';
3
+ import { NativeMessages } from '../../online/agent/messages/projection.js';
4
+ import { OnlineAgentConfigurator } from '../../online/agent/configuration.js';
1
5
  import { outputBlock, TERMINAL_RUN_STATUSES } from '@nocobase/agent-protocol';
2
6
  import { historicalPageContext, hasContent, renderPageContext, } from './page-context.js';
3
7
  import { nativeExecutionStatus, runnerBinding, } from '../../online/agent/persistence/state.js';
@@ -206,6 +210,12 @@ export function createConversationService(deps) {
206
210
  return workspace.resolve(conn, conversation, prepared);
207
211
  }
208
212
  const sources = createSources();
213
+ const shares = createConversationShares({
214
+ tx,
215
+ ids,
216
+ people: deps.people,
217
+ now,
218
+ });
209
219
  const links = createConversationLinks({
210
220
  tx,
211
221
  ids,
@@ -405,7 +415,48 @@ export function createConversationService(deps) {
405
415
  }
406
416
  async function detail(userId, id) {
407
417
  const conn = tx.read();
408
- return detailOf(conn, await owned(conn, userId, id));
418
+ const { record, share } = await conversationAccess(conn, userId, id);
419
+ if (!share)
420
+ return detailOf(conn, record);
421
+ // Whitelist snapshot fields: no latest runner, project, execution, usage, wait or owner attention.
422
+ return {
423
+ id,
424
+ title: share.title,
425
+ titleSource: 'user',
426
+ category: 'chat',
427
+ showInChatList: false,
428
+ source: 'panel',
429
+ mode: record.mode,
430
+ agent: jsonObject(record.metadata).onlineAgent
431
+ ? {
432
+ id: 'online',
433
+ name: 'Online agent',
434
+ nameText: null,
435
+ avatar: null,
436
+ archived: false,
437
+ }
438
+ : {
439
+ ...agentRef(record.agentId, record.agentId ? await findAgent(conn, record.agentId) : null),
440
+ avatar: null,
441
+ archived: false,
442
+ },
443
+ fallbackFrom: null,
444
+ read: true,
445
+ lastMessageAt: share.snapshotAt,
446
+ archivedAt: null,
447
+ createdAt: record.createdAt,
448
+ updatedAt: share.updatedAt,
449
+ run: null,
450
+ lastSeq: Number(share.cutoffSeq),
451
+ links: [],
452
+ availability: { online: false, reason: null, onlineRunners: 0 },
453
+ canFallback: false,
454
+ canRestore: false,
455
+ snapshot: {
456
+ cutoffSeq: Number(share.cutoffSeq),
457
+ snapshotAt: share.snapshotAt,
458
+ },
459
+ };
409
460
  }
410
461
  // -------------------------------------------------------------------------------------------------------------------
411
462
  // Writing
@@ -745,6 +796,9 @@ export function createConversationService(deps) {
745
796
  const released = deps.attachments
746
797
  ? await deps.attachments.release(unit.conn, record.id)
747
798
  : async () => { };
799
+ await sharesRepo(unit.conn).deleteMany({
800
+ filter: { conversationId: record.id },
801
+ });
748
802
  await messagesRepo(unit.conn).deleteMany({
749
803
  filter: { conversationId: record.id },
750
804
  });
@@ -1360,6 +1414,81 @@ export function createConversationService(deps) {
1360
1414
  }
1361
1415
  const service = {
1362
1416
  binding,
1417
+ shares,
1418
+ async snapshotMessages(userId, id, query) {
1419
+ const conn = tx.read();
1420
+ const { record, share } = await conversationAccess(conn, userId, id);
1421
+ if (!share)
1422
+ return null;
1423
+ const cutoff = Number(share.cutoffSeq);
1424
+ let page;
1425
+ if (record.mode === 'runner' || !jsonObject(record.metadata).onlineAgent)
1426
+ page = await runnerUIPage(tx, id, cutoff, query, deps.basePath?.() ?? '', cutoff);
1427
+ else {
1428
+ const rows = await messagesRepo(conn).findMany({
1429
+ filter: (f) => f.and([
1430
+ f.string('conversationId').eq(id),
1431
+ f.number('seq').lte(cutoff),
1432
+ ...(query.ids
1433
+ ? [f.or(query.ids.map((key) => f.string('id').eq(key)))]
1434
+ : []),
1435
+ ...(query.before !== undefined
1436
+ ? [f.number('seq').lt(query.before)]
1437
+ : []),
1438
+ ...(query.after !== undefined
1439
+ ? [f.number('seq').gt(query.after)]
1440
+ : []),
1441
+ ]),
1442
+ sort: (s) => query.after !== undefined || query.ids
1443
+ ? s.field('seq').asc()
1444
+ : s.field('seq').desc(),
1445
+ limit: query.ids ? query.ids.length : query.limit + 1,
1446
+ });
1447
+ const hasMore = !query.ids && rows.length > query.limit;
1448
+ const selected = rows.slice(0, query.ids ? rows.length : query.limit);
1449
+ if (query.after === undefined && !query.ids)
1450
+ selected.reverse();
1451
+ const native = new NativeMessages(new OnlineAgentConfigurator());
1452
+ page = {
1453
+ items: selected.length
1454
+ ? await (deps.nativeHistory ??
1455
+ (async (values) => native.public(await native.validate(values))))(selected.map((row) => jsonObject(row.content).original))
1456
+ : [],
1457
+ lastSeq: cutoff,
1458
+ hasMore,
1459
+ ...(query.after !== undefined && hasMore && selected.length
1460
+ ? { nextAfter: Number(selected.at(-1).seq) }
1461
+ : {}),
1462
+ };
1463
+ }
1464
+ for (const message of page.items) {
1465
+ if (message.metadata) {
1466
+ delete message.metadata.queue;
1467
+ delete message.metadata.executionId;
1468
+ delete message.metadata.turnId;
1469
+ }
1470
+ // A shared transcript contains historical content; linked records are always resolved as this viewer.
1471
+ if (message.metadata?.context) {
1472
+ const context = message.metadata.context;
1473
+ message.metadata.context = await deps.contextKinds.resolve(conn, userId, {
1474
+ route: '',
1475
+ items: context.items.map(({ kind, id }) => ({ kind, id })),
1476
+ });
1477
+ }
1478
+ const indexes = message.parts.flatMap((part, index) => part.type === 'data-turn' || part.type === 'data-phase'
1479
+ ? []
1480
+ : [index]);
1481
+ if (message.metadata?.sourceRecords)
1482
+ message.metadata.sourceRecords = message.metadata.sourceRecords
1483
+ .filter((source) => indexes.includes(source.partIndex))
1484
+ .map((source) => ({
1485
+ ...source,
1486
+ partIndex: indexes.indexOf(source.partIndex),
1487
+ }));
1488
+ message.parts = indexes.map((index) => message.parts[index]);
1489
+ }
1490
+ return page;
1491
+ },
1363
1492
  contextKinds: deps.contextKinds,
1364
1493
  sources,
1365
1494
  ownedTitles,