devchain-cli 0.20.0 → 0.20.1
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/dist/node_modules/@devchain/shared/__fixtures__/phase2-frames.d.ts +0 -1
- package/dist/node_modules/@devchain/shared/__fixtures__/phase2-frames.d.ts.map +1 -1
- package/dist/node_modules/@devchain/shared/__fixtures__/phase2-frames.js +0 -2
- package/dist/node_modules/@devchain/shared/__fixtures__/phase2-frames.js.map +1 -1
- package/dist/node_modules/@devchain/shared/schemas/export-schema.d.ts +114 -11
- package/dist/node_modules/@devchain/shared/schemas/export-schema.d.ts.map +1 -1
- package/dist/node_modules/@devchain/shared/schemas/export-schema.js +11 -8
- package/dist/node_modules/@devchain/shared/schemas/export-schema.js.map +1 -1
- package/dist/node_modules/@devchain/shared/tsconfig.tsbuildinfo +1 -1
- package/dist/node_modules/@devchain/shared/tunnel-protocol.d.ts.map +1 -1
- package/dist/node_modules/@devchain/shared/tunnel-protocol.js +0 -1
- package/dist/node_modules/@devchain/shared/tunnel-protocol.js.map +1 -1
- package/dist/server/app.main.module.js +0 -2
- package/dist/server/app.main.module.js.map +1 -1
- package/dist/server/app.normal.module.js +0 -2
- package/dist/server/app.normal.module.js.map +1 -1
- package/dist/server/common/test/app-bootstrap.helper.js +1 -0
- package/dist/server/common/test/app-bootstrap.helper.js.map +1 -1
- package/dist/server/modules/agent-message-delivery/adapters/legacy-delivery-formatter.adapter.js +0 -5
- package/dist/server/modules/agent-message-delivery/adapters/legacy-delivery-formatter.adapter.js.map +1 -1
- package/dist/server/modules/agent-message-delivery/adapters/legacy-recipient-resolver.adapter.d.ts +1 -3
- package/dist/server/modules/agent-message-delivery/adapters/legacy-recipient-resolver.adapter.js +1 -1
- package/dist/server/modules/agent-message-delivery/adapters/legacy-recipient-resolver.adapter.js.map +1 -1
- package/dist/server/modules/agent-message-delivery/agent-message-delivery.module.js +0 -2
- package/dist/server/modules/agent-message-delivery/agent-message-delivery.module.js.map +1 -1
- package/dist/server/modules/agent-message-delivery/agent-message-delivery.service.js +1 -3
- package/dist/server/modules/agent-message-delivery/agent-message-delivery.service.js.map +1 -1
- package/dist/server/modules/agent-message-delivery/dtos/delivery.types.d.ts +1 -3
- package/dist/server/modules/agent-message-delivery/ports/delivery-recipient-resolver.d.ts +1 -3
- package/dist/server/modules/agent-message-delivery/ports/delivery-recipient-resolver.js.map +1 -1
- package/dist/server/modules/agents/controllers/agents.controller.js +4 -1
- package/dist/server/modules/agents/controllers/agents.controller.js.map +1 -1
- package/dist/server/modules/cloud-tunnel/services/mobile-chat-rpc.service.js.map +1 -1
- package/dist/server/modules/cloud-tunnel/services/tunnel-event-forwarder.service.d.ts +1 -1
- package/dist/server/modules/cloud-tunnel/services/tunnel-event-forwarder.service.js +0 -8
- package/dist/server/modules/cloud-tunnel/services/tunnel-event-forwarder.service.js.map +1 -1
- package/dist/server/modules/epics/subscribers/epic-assignment-notifier.subscriber.d.ts +6 -0
- package/dist/server/modules/epics/subscribers/epic-assignment-notifier.subscriber.js +111 -34
- package/dist/server/modules/epics/subscribers/epic-assignment-notifier.subscriber.js.map +1 -1
- package/dist/server/modules/events/catalog/broadcast-registry.js +0 -21
- package/dist/server/modules/events/catalog/broadcast-registry.js.map +1 -1
- package/dist/server/modules/events/catalog/index.d.ts +6 -16
- package/dist/server/modules/events/catalog/index.js +0 -2
- package/dist/server/modules/events/catalog/index.js.map +1 -1
- package/dist/server/modules/events/catalog/session.stopped.d.ts +14 -0
- package/dist/server/modules/events/catalog/session.stopped.js +10 -1
- package/dist/server/modules/events/catalog/session.stopped.js.map +1 -1
- package/dist/server/modules/mcp/constants.d.ts +0 -4
- package/dist/server/modules/mcp/constants.js +1 -15
- package/dist/server/modules/mcp/constants.js.map +1 -1
- package/dist/server/modules/mcp/dtos/mcp.dto.d.ts +0 -319
- package/dist/server/modules/mcp/dtos/mcp.dto.js +1 -100
- package/dist/server/modules/mcp/dtos/mcp.dto.js.map +1 -1
- package/dist/server/modules/mcp/mcp-full.module.js +0 -2
- package/dist/server/modules/mcp/mcp-full.module.js.map +1 -1
- package/dist/server/modules/mcp/services/handlers/chat-context.d.ts +0 -4
- package/dist/server/modules/mcp/services/handlers/chat-tools.d.ts +0 -3
- package/dist/server/modules/mcp/services/handlers/chat-tools.js +71 -382
- package/dist/server/modules/mcp/services/handlers/chat-tools.js.map +1 -1
- package/dist/server/modules/mcp/services/mcp.service.d.ts +1 -4
- package/dist/server/modules/mcp/services/mcp.service.js +22 -44
- package/dist/server/modules/mcp/services/mcp.service.js.map +1 -1
- package/dist/server/modules/mcp/tool-descriptors/chat.bindings.js +0 -3
- package/dist/server/modules/mcp/tool-descriptors/chat.bindings.js.map +1 -1
- package/dist/server/modules/mcp/tool-descriptors/chat.metadata.js +4 -59
- package/dist/server/modules/mcp/tool-descriptors/chat.metadata.js.map +1 -1
- package/dist/server/modules/mcp/tool-descriptors/index.js +0 -4
- package/dist/server/modules/mcp/tool-descriptors/index.js.map +1 -1
- package/dist/server/modules/projects/controllers/projects.controller.d.ts +2 -10
- package/dist/server/modules/projects/helpers/project-export.d.ts +1 -5
- package/dist/server/modules/projects/helpers/project-runtime.helpers.d.ts +2 -5
- package/dist/server/modules/projects/helpers/project-runtime.helpers.js.map +1 -1
- package/dist/server/modules/projects/services/projects.service.d.ts +1 -5
- package/dist/server/modules/projects/template-codec/codecs/subscribers.codec.d.ts +3 -10
- package/dist/server/modules/projects/template-codec/codecs/subscribers.codec.js.map +1 -1
- package/dist/server/modules/registry/controllers/templates.controller.d.ts +12 -1
- package/dist/server/modules/reviews/subscribers/review-comment-notifier.subscriber.js +0 -1
- package/dist/server/modules/reviews/subscribers/review-comment-notifier.subscriber.js.map +1 -1
- package/dist/server/modules/session-reader/data/pricing.json +1 -1
- package/dist/server/modules/sessions/controllers/sessions.controller.js +4 -1
- package/dist/server/modules/sessions/controllers/sessions.controller.js.map +1 -1
- package/dist/server/modules/sessions/services/session-lifecycle-facade.service.js +8 -2
- package/dist/server/modules/sessions/services/session-lifecycle-facade.service.js.map +1 -1
- package/dist/server/modules/sessions/services/session-runtime/__test-utils__/pipeline-harness.d.ts +2 -0
- package/dist/server/modules/sessions/services/session-runtime/__test-utils__/pipeline-harness.js +2 -0
- package/dist/server/modules/sessions/services/session-runtime/__test-utils__/pipeline-harness.js.map +1 -1
- package/dist/server/modules/sessions/services/session-runtime/session-launch-pipeline.service.js +3 -5
- package/dist/server/modules/sessions/services/session-runtime/session-launch-pipeline.service.js.map +1 -1
- package/dist/server/modules/sessions/services/session-runtime/session-restore-pipeline.service.js +3 -5
- package/dist/server/modules/sessions/services/session-runtime/session-restore-pipeline.service.js.map +1 -1
- package/dist/server/modules/sessions/services/sessions.service.d.ts +2 -2
- package/dist/server/modules/sessions/services/sessions.service.js +70 -97
- package/dist/server/modules/sessions/services/sessions.service.js.map +1 -1
- package/dist/server/modules/storage/interfaces/storage.interface.d.ts +0 -1
- package/dist/server/modules/storage/interfaces/storage.interface.js.map +1 -1
- package/dist/server/modules/storage/local/delegates/review.delegate.d.ts +0 -1
- package/dist/server/modules/storage/local/delegates/review.delegate.js +0 -20
- package/dist/server/modules/storage/local/delegates/review.delegate.js.map +1 -1
- package/dist/server/modules/storage/local/local-storage.service.d.ts +0 -1
- package/dist/server/modules/storage/local/local-storage.service.js +0 -3
- package/dist/server/modules/storage/local/local-storage.service.js.map +1 -1
- package/dist/server/modules/storage/models/domain.models.d.ts +7 -2
- package/dist/server/modules/subscribers/actions/restart-agent.action.js +4 -1
- package/dist/server/modules/subscribers/actions/restart-agent.action.js.map +1 -1
- package/dist/server/modules/subscribers/dtos/subscriber.dto.d.ts +227 -19
- package/dist/server/modules/subscribers/dtos/subscriber.dto.js +10 -5
- package/dist/server/modules/subscribers/dtos/subscriber.dto.js.map +1 -1
- package/dist/server/modules/subscribers/events/event-fields-catalog.js +6 -1
- package/dist/server/modules/subscribers/events/event-fields-catalog.js.map +1 -1
- package/dist/server/modules/subscribers/services/subscriber-executor.service.d.ts +3 -0
- package/dist/server/modules/subscribers/services/subscriber-executor.service.js +44 -0
- package/dist/server/modules/subscribers/services/subscriber-executor.service.js.map +1 -1
- package/dist/server/modules/teams/services/teams.service.js +4 -1
- package/dist/server/modules/teams/services/teams.service.js.map +1 -1
- package/dist/server/modules/teams/subscribers/team-membership-changed-notifier.subscriber.js +3 -1
- package/dist/server/modules/teams/subscribers/team-membership-changed-notifier.subscriber.js.map +1 -1
- package/dist/server/modules/terminal/gateways/terminal.gateway.d.ts +0 -6
- package/dist/server/modules/terminal/gateways/terminal.gateway.js +1 -33
- package/dist/server/modules/terminal/gateways/terminal.gateway.js.map +1 -1
- package/dist/server/modules/terminal/services/terminal-io/lifecycle.d.ts +2 -1
- package/dist/server/modules/terminal/services/terminal-io/lifecycle.js +38 -0
- package/dist/server/modules/terminal/services/terminal-io/lifecycle.js.map +1 -1
- package/dist/server/modules/terminal/services/terminal-io/terminal-io.service.d.ts +13 -2
- package/dist/server/modules/terminal/services/terminal-io/terminal-io.service.js +141 -25
- package/dist/server/modules/terminal/services/terminal-io/terminal-io.service.js.map +1 -1
- package/dist/server/modules/terminal/services/terminal-io/types.d.ts +15 -0
- package/dist/server/templates/teams-dev.json +157 -104
- package/dist/server/tsconfig.tsbuildinfo +1 -1
- package/dist/server/ui/assets/{ReviewDetailPage-Cf5ED0R0.js → ReviewDetailPage-BZoAe0G2.js} +1 -1
- package/dist/server/ui/assets/{ReviewsPage-BfP9P3QO.js → ReviewsPage-J3XZDw7k.js} +1 -1
- package/dist/server/ui/assets/index-CxmSxl5f.css +32 -0
- package/dist/server/ui/assets/index-DoKUmi74.js +1153 -0
- package/dist/server/ui/assets/{useReviewSubscription-QJSfZ3FX.js → useReviewSubscription-CNUx-AWQ.js} +19 -19
- package/dist/server/ui/index.html +2 -2
- package/dist/templates/teams-dev.json +157 -104
- package/package.json +8 -1
- package/dist/drizzle/PHASE2_MIGRATION_GUIDE.md +0 -109
- package/dist/server/modules/agent-message-delivery/subscribers/chat-message-delivery.subscriber.d.ts +0 -22
- package/dist/server/modules/agent-message-delivery/subscribers/chat-message-delivery.subscriber.js +0 -64
- package/dist/server/modules/agent-message-delivery/subscribers/chat-message-delivery.subscriber.js.map +0 -1
- package/dist/server/modules/chat/chat.module.d.ts +0 -2
- package/dist/server/modules/chat/chat.module.js +0 -38
- package/dist/server/modules/chat/chat.module.js.map +0 -1
- package/dist/server/modules/chat/controllers/chat-settings.controller.d.ts +0 -8
- package/dist/server/modules/chat/controllers/chat-settings.controller.js +0 -67
- package/dist/server/modules/chat/controllers/chat-settings.controller.js.map +0 -1
- package/dist/server/modules/chat/controllers/chat.controller.d.ts +0 -15
- package/dist/server/modules/chat/controllers/chat.controller.js +0 -153
- package/dist/server/modules/chat/controllers/chat.controller.js.map +0 -1
- package/dist/server/modules/chat/dtos/chat-settings.dto.d.ts +0 -31
- package/dist/server/modules/chat/dtos/chat-settings.dto.js +0 -17
- package/dist/server/modules/chat/dtos/chat-settings.dto.js.map +0 -1
- package/dist/server/modules/chat/dtos/chat.dto.d.ts +0 -309
- package/dist/server/modules/chat/dtos/chat.dto.js +0 -80
- package/dist/server/modules/chat/dtos/chat.dto.js.map +0 -1
- package/dist/server/modules/chat/services/chat-session-invite.service.d.ts +0 -16
- package/dist/server/modules/chat/services/chat-session-invite.service.js +0 -200
- package/dist/server/modules/chat/services/chat-session-invite.service.js.map +0 -1
- package/dist/server/modules/chat/services/chat-settings.service.d.ts +0 -12
- package/dist/server/modules/chat/services/chat-settings.service.js +0 -123
- package/dist/server/modules/chat/services/chat-settings.service.js.map +0 -1
- package/dist/server/modules/chat/services/chat.service.d.ts +0 -47
- package/dist/server/modules/chat/services/chat.service.js +0 -693
- package/dist/server/modules/chat/services/chat.service.js.map +0 -1
- package/dist/server/modules/chat/services/invite-template.util.d.ts +0 -17
- package/dist/server/modules/chat/services/invite-template.util.js +0 -70
- package/dist/server/modules/chat/services/invite-template.util.js.map +0 -1
- package/dist/server/modules/events/catalog/chat.message.read.d.ts +0 -21
- package/dist/server/modules/events/catalog/chat.message.read.js +0 -14
- package/dist/server/modules/events/catalog/chat.message.read.js.map +0 -1
- package/dist/server/modules/mcp/services/handlers/activity-context.d.ts +0 -6
- package/dist/server/modules/mcp/services/handlers/activity-context.js +0 -3
- package/dist/server/modules/mcp/services/handlers/activity-context.js.map +0 -1
- package/dist/server/modules/mcp/services/handlers/activity-tools.d.ts +0 -4
- package/dist/server/modules/mcp/services/handlers/activity-tools.js +0 -179
- package/dist/server/modules/mcp/services/handlers/activity-tools.js.map +0 -1
- package/dist/server/modules/mcp/tool-descriptors/activity.bindings.d.ts +0 -2
- package/dist/server/modules/mcp/tool-descriptors/activity.bindings.js +0 -9
- package/dist/server/modules/mcp/tool-descriptors/activity.bindings.js.map +0 -1
- package/dist/server/modules/mcp/tool-descriptors/activity.metadata.d.ts +0 -2
- package/dist/server/modules/mcp/tool-descriptors/activity.metadata.js +0 -49
- package/dist/server/modules/mcp/tool-descriptors/activity.metadata.js.map +0 -1
- package/dist/server/ui/assets/index-B5ZC_DQU.css +0 -32
- package/dist/server/ui/assets/index-DptgqA22.js +0 -1156
|
@@ -1,693 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
19
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
20
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
21
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
22
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
23
|
-
};
|
|
24
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
-
var ownKeys = function(o) {
|
|
26
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
-
var ar = [];
|
|
28
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
-
return ar;
|
|
30
|
-
};
|
|
31
|
-
return ownKeys(o);
|
|
32
|
-
};
|
|
33
|
-
return function (mod) {
|
|
34
|
-
if (mod && mod.__esModule) return mod;
|
|
35
|
-
var result = {};
|
|
36
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
-
__setModuleDefault(result, mod);
|
|
38
|
-
return result;
|
|
39
|
-
};
|
|
40
|
-
})();
|
|
41
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
42
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
43
|
-
};
|
|
44
|
-
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
45
|
-
return function (target, key) { decorator(target, key, paramIndex); }
|
|
46
|
-
};
|
|
47
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
-
exports.ChatService = void 0;
|
|
49
|
-
const common_1 = require("@nestjs/common");
|
|
50
|
-
const error_types_1 = require("../../../common/errors/error-types");
|
|
51
|
-
const event_emitter_1 = require("@nestjs/event-emitter");
|
|
52
|
-
const db_provider_1 = require("../../storage/db/db.provider");
|
|
53
|
-
const better_sqlite3_1 = require("drizzle-orm/better-sqlite3");
|
|
54
|
-
const drizzle_orm_1 = require("drizzle-orm");
|
|
55
|
-
const crypto_1 = require("crypto");
|
|
56
|
-
const logger_1 = require("../../../common/logging/logger");
|
|
57
|
-
const schema_1 = require("../../storage/db/schema");
|
|
58
|
-
const chat_settings_service_1 = require("./chat-settings.service");
|
|
59
|
-
const chat_session_invite_service_1 = require("./chat-session-invite.service");
|
|
60
|
-
const invite_template_util_1 = require("./invite-template.util");
|
|
61
|
-
const logger = (0, logger_1.createLogger)('ChatService');
|
|
62
|
-
const DEFAULT_INVITER_NAME = 'You';
|
|
63
|
-
let ChatService = class ChatService {
|
|
64
|
-
db;
|
|
65
|
-
eventEmitter;
|
|
66
|
-
chatSettingsService;
|
|
67
|
-
chatSessionInviteService;
|
|
68
|
-
constructor(db, eventEmitter, chatSettingsService, chatSessionInviteService) {
|
|
69
|
-
this.db = db;
|
|
70
|
-
this.eventEmitter = eventEmitter;
|
|
71
|
-
this.chatSettingsService = chatSettingsService;
|
|
72
|
-
this.chatSessionInviteService = chatSessionInviteService;
|
|
73
|
-
logger.info('ChatService initialized');
|
|
74
|
-
}
|
|
75
|
-
deriveThreadTitle(thread, participantNames) {
|
|
76
|
-
if (thread.title && thread.title.trim().length > 0) {
|
|
77
|
-
return thread.title;
|
|
78
|
-
}
|
|
79
|
-
return participantNames || 'Chat Thread';
|
|
80
|
-
}
|
|
81
|
-
async sendInviteMessage(threadId, projectId, agentName, threadTitle, participantNames, inviterName = DEFAULT_INVITER_NAME) {
|
|
82
|
-
const inviteTemplate = await this.chatSettingsService.getInviteTemplate(projectId);
|
|
83
|
-
const inviteMessageId = (0, crypto_1.randomUUID)();
|
|
84
|
-
const messageTimestamp = new Date().toISOString();
|
|
85
|
-
const renderedTemplate = (0, invite_template_util_1.renderInviteTemplate)(inviteTemplate, {
|
|
86
|
-
threadId,
|
|
87
|
-
threadTitle,
|
|
88
|
-
inviterName,
|
|
89
|
-
participantNames,
|
|
90
|
-
invitedAgentName: agentName,
|
|
91
|
-
createdAt: messageTimestamp,
|
|
92
|
-
messageId: inviteMessageId,
|
|
93
|
-
});
|
|
94
|
-
await this.persistMessage(threadId, {
|
|
95
|
-
messageId: inviteMessageId,
|
|
96
|
-
authorType: 'system',
|
|
97
|
-
content: renderedTemplate,
|
|
98
|
-
createdAt: messageTimestamp,
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
async persistMessage(threadId, data) {
|
|
102
|
-
const createdAt = data.createdAt ?? new Date().toISOString();
|
|
103
|
-
const messageId = data.messageId ?? (0, crypto_1.randomUUID)();
|
|
104
|
-
const effectiveTargets = data.authorType === 'user' && data.targets && data.targets.length > 0 ? data.targets : [];
|
|
105
|
-
await this.db.insert(schema_1.chatMessages).values({
|
|
106
|
-
id: messageId,
|
|
107
|
-
threadId,
|
|
108
|
-
authorType: data.authorType,
|
|
109
|
-
authorAgentId: data.authorAgentId ?? null,
|
|
110
|
-
content: data.content,
|
|
111
|
-
createdAt,
|
|
112
|
-
});
|
|
113
|
-
if (effectiveTargets.length > 0) {
|
|
114
|
-
const targetValues = effectiveTargets.map((agentId) => ({
|
|
115
|
-
id: (0, crypto_1.randomUUID)(),
|
|
116
|
-
messageId,
|
|
117
|
-
agentId,
|
|
118
|
-
createdAt,
|
|
119
|
-
}));
|
|
120
|
-
await this.db.insert(schema_1.chatMessageTargets).values(targetValues);
|
|
121
|
-
}
|
|
122
|
-
await this.db
|
|
123
|
-
.update(schema_1.chatThreads)
|
|
124
|
-
.set({ updatedAt: createdAt })
|
|
125
|
-
.where((0, drizzle_orm_1.eq)(schema_1.chatThreads.id, threadId));
|
|
126
|
-
const message = {
|
|
127
|
-
id: messageId,
|
|
128
|
-
threadId,
|
|
129
|
-
authorType: data.authorType,
|
|
130
|
-
authorAgentId: data.authorAgentId ?? null,
|
|
131
|
-
content: data.content,
|
|
132
|
-
targets: effectiveTargets.length > 0 ? effectiveTargets : undefined,
|
|
133
|
-
createdAt,
|
|
134
|
-
};
|
|
135
|
-
let projectId;
|
|
136
|
-
let recipientIds;
|
|
137
|
-
try {
|
|
138
|
-
const threadRow = await this.db
|
|
139
|
-
.select({ projectId: schema_1.chatThreads.projectId })
|
|
140
|
-
.from(schema_1.chatThreads)
|
|
141
|
-
.where((0, drizzle_orm_1.eq)(schema_1.chatThreads.id, threadId))
|
|
142
|
-
.limit(1);
|
|
143
|
-
projectId = threadRow[0]?.projectId;
|
|
144
|
-
if (data.authorType === 'user') {
|
|
145
|
-
if (effectiveTargets.length > 0) {
|
|
146
|
-
recipientIds = effectiveTargets;
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
const members = await this.db
|
|
150
|
-
.select({ agentId: schema_1.chatMembers.agentId })
|
|
151
|
-
.from(schema_1.chatMembers)
|
|
152
|
-
.where((0, drizzle_orm_1.eq)(schema_1.chatMembers.threadId, threadId));
|
|
153
|
-
recipientIds = members.map((m) => m.agentId);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
catch {
|
|
158
|
-
}
|
|
159
|
-
try {
|
|
160
|
-
this.eventEmitter.emit('chat.message.created', {
|
|
161
|
-
threadId,
|
|
162
|
-
projectId,
|
|
163
|
-
recipientIds,
|
|
164
|
-
message,
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
catch (error) {
|
|
168
|
-
logger.warn({ error, threadId, messageId }, 'Failed to emit chat.message.created event');
|
|
169
|
-
}
|
|
170
|
-
return message;
|
|
171
|
-
}
|
|
172
|
-
async listThreads(query) {
|
|
173
|
-
const { projectId, createdByType, limit, offset } = query;
|
|
174
|
-
const conditions = [(0, drizzle_orm_1.eq)(schema_1.chatThreads.projectId, projectId)];
|
|
175
|
-
if (createdByType) {
|
|
176
|
-
conditions.push((0, drizzle_orm_1.eq)(schema_1.chatThreads.createdByType, createdByType));
|
|
177
|
-
}
|
|
178
|
-
const whereClause = (0, drizzle_orm_1.and)(...conditions);
|
|
179
|
-
const threads = await this.db
|
|
180
|
-
.select()
|
|
181
|
-
.from(schema_1.chatThreads)
|
|
182
|
-
.where(whereClause)
|
|
183
|
-
.orderBy((0, drizzle_orm_1.desc)(schema_1.chatThreads.updatedAt))
|
|
184
|
-
.limit(limit)
|
|
185
|
-
.offset(offset);
|
|
186
|
-
const countResult = await this.db
|
|
187
|
-
.select({ count: schema_1.chatThreads.id })
|
|
188
|
-
.from(schema_1.chatThreads)
|
|
189
|
-
.where(whereClause);
|
|
190
|
-
const total = countResult.length;
|
|
191
|
-
const threadIds = threads.map((t) => t.id);
|
|
192
|
-
const membersRows = threadIds.length > 0
|
|
193
|
-
? await this.db.select().from(schema_1.chatMembers).where((0, drizzle_orm_1.inArray)(schema_1.chatMembers.threadId, threadIds))
|
|
194
|
-
: [];
|
|
195
|
-
const membersByThread = new Map();
|
|
196
|
-
for (const row of membersRows) {
|
|
197
|
-
if (!membersByThread.has(row.threadId)) {
|
|
198
|
-
membersByThread.set(row.threadId, []);
|
|
199
|
-
}
|
|
200
|
-
membersByThread.get(row.threadId).push(row.agentId);
|
|
201
|
-
}
|
|
202
|
-
const items = threads.map((thread) => ({
|
|
203
|
-
id: thread.id,
|
|
204
|
-
projectId: thread.projectId,
|
|
205
|
-
title: thread.title,
|
|
206
|
-
isGroup: thread.isGroup,
|
|
207
|
-
createdByType: thread.createdByType,
|
|
208
|
-
createdByUserId: thread.createdByUserId,
|
|
209
|
-
createdByAgentId: thread.createdByAgentId,
|
|
210
|
-
members: membersByThread.get(thread.id) ?? [],
|
|
211
|
-
createdAt: thread.createdAt,
|
|
212
|
-
updatedAt: thread.updatedAt,
|
|
213
|
-
}));
|
|
214
|
-
return {
|
|
215
|
-
items,
|
|
216
|
-
total,
|
|
217
|
-
limit,
|
|
218
|
-
offset,
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
async getThread(threadId) {
|
|
222
|
-
const thread = await this.db
|
|
223
|
-
.select()
|
|
224
|
-
.from(schema_1.chatThreads)
|
|
225
|
-
.where((0, drizzle_orm_1.eq)(schema_1.chatThreads.id, threadId))
|
|
226
|
-
.limit(1);
|
|
227
|
-
if (thread.length === 0) {
|
|
228
|
-
throw new common_1.NotFoundException(`Thread ${threadId} not found`);
|
|
229
|
-
}
|
|
230
|
-
const members = await this.db
|
|
231
|
-
.select()
|
|
232
|
-
.from(schema_1.chatMembers)
|
|
233
|
-
.where((0, drizzle_orm_1.eq)(schema_1.chatMembers.threadId, threadId));
|
|
234
|
-
return {
|
|
235
|
-
id: thread[0].id,
|
|
236
|
-
projectId: thread[0].projectId,
|
|
237
|
-
title: thread[0].title,
|
|
238
|
-
isGroup: thread[0].isGroup,
|
|
239
|
-
createdByType: thread[0].createdByType,
|
|
240
|
-
createdByUserId: thread[0].createdByUserId,
|
|
241
|
-
createdByAgentId: thread[0].createdByAgentId,
|
|
242
|
-
members: members.map((m) => m.agentId),
|
|
243
|
-
createdAt: thread[0].createdAt,
|
|
244
|
-
updatedAt: thread[0].updatedAt,
|
|
245
|
-
};
|
|
246
|
-
}
|
|
247
|
-
async createDirectThread(data) {
|
|
248
|
-
const now = new Date().toISOString();
|
|
249
|
-
const threadId = (0, crypto_1.randomUUID)();
|
|
250
|
-
const existingThreads = await this.db
|
|
251
|
-
.select()
|
|
252
|
-
.from(schema_1.chatThreads)
|
|
253
|
-
.where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema_1.chatThreads.projectId, data.projectId), (0, drizzle_orm_1.eq)(schema_1.chatThreads.isGroup, false), (0, drizzle_orm_1.eq)(schema_1.chatThreads.createdByType, 'user')));
|
|
254
|
-
for (const thread of existingThreads) {
|
|
255
|
-
const members = await this.db
|
|
256
|
-
.select()
|
|
257
|
-
.from(schema_1.chatMembers)
|
|
258
|
-
.where((0, drizzle_orm_1.eq)(schema_1.chatMembers.threadId, thread.id));
|
|
259
|
-
if (members.length === 1 && members[0].agentId === data.agentId) {
|
|
260
|
-
return this.getThread(thread.id);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
await this.db.insert(schema_1.chatThreads).values({
|
|
264
|
-
id: threadId,
|
|
265
|
-
projectId: data.projectId,
|
|
266
|
-
title: null,
|
|
267
|
-
isGroup: false,
|
|
268
|
-
createdByType: 'user',
|
|
269
|
-
createdByUserId: null,
|
|
270
|
-
createdByAgentId: null,
|
|
271
|
-
createdAt: now,
|
|
272
|
-
updatedAt: now,
|
|
273
|
-
});
|
|
274
|
-
await this.db.insert(schema_1.chatMembers).values({
|
|
275
|
-
threadId,
|
|
276
|
-
agentId: data.agentId,
|
|
277
|
-
createdAt: now,
|
|
278
|
-
});
|
|
279
|
-
const agentRow = await this.db
|
|
280
|
-
.select({
|
|
281
|
-
id: schema_1.agents.id,
|
|
282
|
-
name: schema_1.agents.name,
|
|
283
|
-
})
|
|
284
|
-
.from(schema_1.agents)
|
|
285
|
-
.where((0, drizzle_orm_1.eq)(schema_1.agents.id, data.agentId))
|
|
286
|
-
.limit(1);
|
|
287
|
-
if (agentRow.length > 0) {
|
|
288
|
-
const agent = agentRow[0];
|
|
289
|
-
await this.sendInviteMessage(threadId, data.projectId, agent.name, agent.name, agent.name);
|
|
290
|
-
}
|
|
291
|
-
logger.info({ threadId, agentId: data.agentId }, 'Created direct thread');
|
|
292
|
-
return this.getThread(threadId);
|
|
293
|
-
}
|
|
294
|
-
async createGroupThread(data) {
|
|
295
|
-
const now = new Date().toISOString();
|
|
296
|
-
const threadId = (0, crypto_1.randomUUID)();
|
|
297
|
-
if (data.agentIds.length < 2) {
|
|
298
|
-
throw new error_types_1.ValidationError('Group threads require at least 2 agents', {
|
|
299
|
-
provided: data.agentIds.length,
|
|
300
|
-
required: 2,
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
await this.db.insert(schema_1.chatThreads).values({
|
|
304
|
-
id: threadId,
|
|
305
|
-
projectId: data.projectId,
|
|
306
|
-
title: data.title ?? null,
|
|
307
|
-
isGroup: true,
|
|
308
|
-
createdByType: data.createdByType ?? 'user',
|
|
309
|
-
createdByUserId: null,
|
|
310
|
-
createdByAgentId: data.createdByAgentId ?? null,
|
|
311
|
-
createdAt: now,
|
|
312
|
-
updatedAt: now,
|
|
313
|
-
});
|
|
314
|
-
const memberValues = data.agentIds.map((agentId) => ({
|
|
315
|
-
threadId,
|
|
316
|
-
agentId,
|
|
317
|
-
createdAt: now,
|
|
318
|
-
}));
|
|
319
|
-
await this.db.insert(schema_1.chatMembers).values(memberValues);
|
|
320
|
-
logger.info({ threadId, agentIds: data.agentIds, title: data.title }, 'Created group thread');
|
|
321
|
-
return this.getThread(threadId);
|
|
322
|
-
}
|
|
323
|
-
async inviteMembers(threadId, data) {
|
|
324
|
-
const thread = await this.getThread(threadId);
|
|
325
|
-
if (data.projectId && thread.projectId !== data.projectId) {
|
|
326
|
-
throw new error_types_1.ValidationError('Thread does not belong to the specified project', {
|
|
327
|
-
threadId,
|
|
328
|
-
threadProjectId: thread.projectId,
|
|
329
|
-
requestedProjectId: data.projectId,
|
|
330
|
-
});
|
|
331
|
-
}
|
|
332
|
-
if (!thread.isGroup || thread.createdByType !== 'user') {
|
|
333
|
-
throw new error_types_1.ValidationError('Invites are only supported for user-created group threads', {
|
|
334
|
-
threadId,
|
|
335
|
-
isGroup: thread.isGroup,
|
|
336
|
-
createdByType: thread.createdByType,
|
|
337
|
-
});
|
|
338
|
-
}
|
|
339
|
-
const uniqueAgentIds = Array.from(new Set(data.agentIds));
|
|
340
|
-
if (uniqueAgentIds.length === 0) {
|
|
341
|
-
throw new error_types_1.ValidationError('At least one agent must be specified for invitation', {
|
|
342
|
-
threadId,
|
|
343
|
-
});
|
|
344
|
-
}
|
|
345
|
-
const existingMembers = new Set(thread.members ?? []);
|
|
346
|
-
const agentIdsToAdd = uniqueAgentIds.filter((agentId) => !existingMembers.has(agentId));
|
|
347
|
-
if (agentIdsToAdd.length === 0) {
|
|
348
|
-
throw new error_types_1.ValidationError('All selected agents are already participants in this thread', {
|
|
349
|
-
threadId,
|
|
350
|
-
requestedAgents: uniqueAgentIds,
|
|
351
|
-
});
|
|
352
|
-
}
|
|
353
|
-
const inviterName = data.inviterName?.trim().length
|
|
354
|
-
? data.inviterName.trim()
|
|
355
|
-
: DEFAULT_INVITER_NAME;
|
|
356
|
-
const memberIdsToFetch = Array.from(new Set([...existingMembers, ...agentIdsToAdd]));
|
|
357
|
-
const agentRows = memberIdsToFetch.length > 0
|
|
358
|
-
? await this.db
|
|
359
|
-
.select({
|
|
360
|
-
id: schema_1.agents.id,
|
|
361
|
-
projectId: schema_1.agents.projectId,
|
|
362
|
-
name: schema_1.agents.name,
|
|
363
|
-
})
|
|
364
|
-
.from(schema_1.agents)
|
|
365
|
-
.where((0, drizzle_orm_1.inArray)(schema_1.agents.id, memberIdsToFetch))
|
|
366
|
-
: [];
|
|
367
|
-
const agentMap = new Map(agentRows.map((row) => [row.id, row]));
|
|
368
|
-
const missingAgents = agentIdsToAdd.filter((agentId) => !agentMap.has(agentId));
|
|
369
|
-
if (missingAgents.length > 0) {
|
|
370
|
-
throw new error_types_1.ValidationError(`Agents not found: ${missingAgents
|
|
371
|
-
.map((id) => id.slice(0, 8))
|
|
372
|
-
.join(', ')}. Please verify the selection.`, {
|
|
373
|
-
threadId,
|
|
374
|
-
missingAgents,
|
|
375
|
-
});
|
|
376
|
-
}
|
|
377
|
-
const crossProjectAgents = agentIdsToAdd.filter((agentId) => agentMap.get(agentId).projectId !== thread.projectId);
|
|
378
|
-
if (crossProjectAgents.length > 0) {
|
|
379
|
-
throw new error_types_1.ValidationError('One or more selected agents belong to a different project and cannot be invited.', {
|
|
380
|
-
threadId,
|
|
381
|
-
threadProjectId: thread.projectId,
|
|
382
|
-
crossProjectAgents,
|
|
383
|
-
});
|
|
384
|
-
}
|
|
385
|
-
const membershipInsertedAt = new Date().toISOString();
|
|
386
|
-
await this.db.insert(schema_1.chatMembers).values(agentIdsToAdd.map((agentId) => ({
|
|
387
|
-
threadId,
|
|
388
|
-
agentId,
|
|
389
|
-
createdAt: membershipInsertedAt,
|
|
390
|
-
})));
|
|
391
|
-
agentIdsToAdd.forEach((agentId) => existingMembers.add(agentId));
|
|
392
|
-
const participantNamesList = Array.from(existingMembers)
|
|
393
|
-
.map((agentId) => agentMap.get(agentId)?.name)
|
|
394
|
-
.filter((name) => Boolean(name))
|
|
395
|
-
.sort((a, b) => a.localeCompare(b));
|
|
396
|
-
const participantNames = participantNamesList.length > 0
|
|
397
|
-
? participantNamesList.join(', ')
|
|
398
|
-
: 'Participants unavailable';
|
|
399
|
-
const threadTitle = this.deriveThreadTitle(thread, participantNames);
|
|
400
|
-
for (const agentId of agentIdsToAdd) {
|
|
401
|
-
const invitedAgent = agentMap.get(agentId);
|
|
402
|
-
const messageTimestamp = new Date().toISOString();
|
|
403
|
-
await this.persistMessage(threadId, {
|
|
404
|
-
authorType: 'system',
|
|
405
|
-
content: `You invited ${invitedAgent.name}.`,
|
|
406
|
-
createdAt: messageTimestamp,
|
|
407
|
-
});
|
|
408
|
-
await this.sendInviteMessage(threadId, thread.projectId, invitedAgent.name, threadTitle, participantNames, inviterName);
|
|
409
|
-
}
|
|
410
|
-
logger.info({ threadId, invitedAgents: agentIdsToAdd, inviterName }, 'Invited agents to chat thread');
|
|
411
|
-
return this.getThread(threadId);
|
|
412
|
-
}
|
|
413
|
-
async listAgentInitiatedThreads(query) {
|
|
414
|
-
return this.listThreads({
|
|
415
|
-
...query,
|
|
416
|
-
createdByType: 'agent',
|
|
417
|
-
});
|
|
418
|
-
}
|
|
419
|
-
async listMessages(threadId, query) {
|
|
420
|
-
let { since } = query;
|
|
421
|
-
const { limit, offset } = query;
|
|
422
|
-
const threadRows = await this.db
|
|
423
|
-
.select()
|
|
424
|
-
.from(schema_1.chatThreads)
|
|
425
|
-
.where((0, drizzle_orm_1.eq)(schema_1.chatThreads.id, threadId))
|
|
426
|
-
.limit(1);
|
|
427
|
-
if (!since && threadRows.length > 0 && threadRows[0].lastUserClearedAt) {
|
|
428
|
-
since = threadRows[0].lastUserClearedAt;
|
|
429
|
-
logger.debug({ threadId, defaultSince: since }, 'Using lastUserClearedAt as default since filter');
|
|
430
|
-
}
|
|
431
|
-
const conditions = [(0, drizzle_orm_1.eq)(schema_1.chatMessages.threadId, threadId)];
|
|
432
|
-
if (since) {
|
|
433
|
-
conditions.push((0, drizzle_orm_1.gt)(schema_1.chatMessages.createdAt, since));
|
|
434
|
-
}
|
|
435
|
-
const whereClause = (0, drizzle_orm_1.and)(...conditions);
|
|
436
|
-
const messages = await this.db
|
|
437
|
-
.select()
|
|
438
|
-
.from(schema_1.chatMessages)
|
|
439
|
-
.where(whereClause)
|
|
440
|
-
.orderBy(schema_1.chatMessages.createdAt)
|
|
441
|
-
.limit(limit)
|
|
442
|
-
.offset(offset);
|
|
443
|
-
const countResult = await this.db
|
|
444
|
-
.select({ count: schema_1.chatMessages.id })
|
|
445
|
-
.from(schema_1.chatMessages)
|
|
446
|
-
.where(whereClause);
|
|
447
|
-
const total = countResult.length;
|
|
448
|
-
const messageIds = messages.map((m) => m.id);
|
|
449
|
-
const targetsRows = messageIds.length > 0
|
|
450
|
-
? await this.db
|
|
451
|
-
.select()
|
|
452
|
-
.from(schema_1.chatMessageTargets)
|
|
453
|
-
.where((0, drizzle_orm_1.inArray)(schema_1.chatMessageTargets.messageId, messageIds))
|
|
454
|
-
: [];
|
|
455
|
-
const targetsByMessage = new Map();
|
|
456
|
-
for (const row of targetsRows) {
|
|
457
|
-
if (!targetsByMessage.has(row.messageId)) {
|
|
458
|
-
targetsByMessage.set(row.messageId, []);
|
|
459
|
-
}
|
|
460
|
-
targetsByMessage.get(row.messageId).push(row.agentId);
|
|
461
|
-
}
|
|
462
|
-
const items = messages.map((message) => ({
|
|
463
|
-
id: message.id,
|
|
464
|
-
threadId: message.threadId,
|
|
465
|
-
authorType: message.authorType,
|
|
466
|
-
authorAgentId: message.authorAgentId,
|
|
467
|
-
content: message.content,
|
|
468
|
-
targets: targetsByMessage.get(message.id),
|
|
469
|
-
createdAt: message.createdAt,
|
|
470
|
-
}));
|
|
471
|
-
return {
|
|
472
|
-
items,
|
|
473
|
-
total,
|
|
474
|
-
limit,
|
|
475
|
-
offset,
|
|
476
|
-
};
|
|
477
|
-
}
|
|
478
|
-
async createMessage(threadId, data) {
|
|
479
|
-
const thread = await this.getThread(threadId);
|
|
480
|
-
if (data.projectId && thread.projectId !== data.projectId) {
|
|
481
|
-
throw new error_types_1.ValidationError('Thread does not belong to the specified project', {
|
|
482
|
-
threadId,
|
|
483
|
-
threadProjectId: thread.projectId,
|
|
484
|
-
requestedProjectId: data.projectId,
|
|
485
|
-
});
|
|
486
|
-
}
|
|
487
|
-
if (data.authorType === 'system') {
|
|
488
|
-
throw new error_types_1.ValidationError('System messages cannot be posted via the public API', {
|
|
489
|
-
threadId,
|
|
490
|
-
authorType: data.authorType,
|
|
491
|
-
});
|
|
492
|
-
}
|
|
493
|
-
logger.info({
|
|
494
|
-
threadId,
|
|
495
|
-
authorType: data.authorType,
|
|
496
|
-
hasTargets: Boolean(data.targets && data.targets.length > 0),
|
|
497
|
-
}, 'Creating chat message');
|
|
498
|
-
const targetedAgentIds = data.authorType === 'user' && data.targets && data.targets.length > 0
|
|
499
|
-
? data.targets
|
|
500
|
-
: (thread.members ?? []);
|
|
501
|
-
await this.chatSessionInviteService.ensureSessionInvites(threadId, thread.projectId, targetedAgentIds);
|
|
502
|
-
return this.persistMessage(threadId, data);
|
|
503
|
-
}
|
|
504
|
-
async clearHistory(threadId, data) {
|
|
505
|
-
await this.getThread(threadId);
|
|
506
|
-
const now = new Date().toISOString();
|
|
507
|
-
await this.db
|
|
508
|
-
.update(schema_1.chatThreads)
|
|
509
|
-
.set({ lastUserClearedAt: now, updatedAt: now })
|
|
510
|
-
.where((0, drizzle_orm_1.eq)(schema_1.chatThreads.id, threadId));
|
|
511
|
-
if (data.announce) {
|
|
512
|
-
await this.persistMessage(threadId, {
|
|
513
|
-
authorType: 'system',
|
|
514
|
-
content: 'History cleared.',
|
|
515
|
-
createdAt: now,
|
|
516
|
-
});
|
|
517
|
-
}
|
|
518
|
-
logger.info({ threadId, announce: data.announce }, 'Cleared thread history');
|
|
519
|
-
return this.getThread(threadId);
|
|
520
|
-
}
|
|
521
|
-
async purgeHistory(threadId, data) {
|
|
522
|
-
await this.getThread(threadId);
|
|
523
|
-
const cutoff = data.before ?? new Date().toISOString();
|
|
524
|
-
const idsToDelete = (await this.db
|
|
525
|
-
.select({ id: schema_1.chatMessages.id })
|
|
526
|
-
.from(schema_1.chatMessages)
|
|
527
|
-
.where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema_1.chatMessages.threadId, threadId), (await Promise.resolve().then(() => __importStar(require('drizzle-orm')))).lt(schema_1.chatMessages.createdAt, cutoff)))).map((r) => r.id);
|
|
528
|
-
if (idsToDelete.length > 0) {
|
|
529
|
-
const { lt } = await Promise.resolve().then(() => __importStar(require('drizzle-orm')));
|
|
530
|
-
await this.db
|
|
531
|
-
.delete(schema_1.chatMessages)
|
|
532
|
-
.where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema_1.chatMessages.threadId, threadId), lt(schema_1.chatMessages.createdAt, cutoff)));
|
|
533
|
-
logger.info({ threadId, cutoff, deletedCount: idsToDelete.length }, 'Purged chat messages');
|
|
534
|
-
}
|
|
535
|
-
else {
|
|
536
|
-
logger.info({ threadId, cutoff, deletedCount: 0 }, 'No chat messages to purge');
|
|
537
|
-
}
|
|
538
|
-
if (data.announce) {
|
|
539
|
-
await this.persistMessage(threadId, {
|
|
540
|
-
authorType: 'system',
|
|
541
|
-
content: `History purged up to ${cutoff}.`,
|
|
542
|
-
});
|
|
543
|
-
}
|
|
544
|
-
return this.getThread(threadId);
|
|
545
|
-
}
|
|
546
|
-
async acknowledgeInvite(threadId, messageId, agentId, sessionId) {
|
|
547
|
-
const now = new Date().toISOString();
|
|
548
|
-
const inviteRows = await this.db
|
|
549
|
-
.select()
|
|
550
|
-
.from(schema_1.chatThreadSessionInvites)
|
|
551
|
-
.where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema_1.chatThreadSessionInvites.threadId, threadId), (0, drizzle_orm_1.eq)(schema_1.chatThreadSessionInvites.agentId, agentId), (0, drizzle_orm_1.eq)(schema_1.chatThreadSessionInvites.sessionId, sessionId), (0, drizzle_orm_1.eq)(schema_1.chatThreadSessionInvites.inviteMessageId, messageId)))
|
|
552
|
-
.limit(1);
|
|
553
|
-
if (inviteRows.length === 0) {
|
|
554
|
-
logger.debug({ threadId, messageId, agentId, sessionId }, 'Message is not an invite');
|
|
555
|
-
return;
|
|
556
|
-
}
|
|
557
|
-
const invite = inviteRows[0];
|
|
558
|
-
if (!invite.acknowledgedAt) {
|
|
559
|
-
await this.db
|
|
560
|
-
.update(schema_1.chatThreadSessionInvites)
|
|
561
|
-
.set({ acknowledgedAt: now })
|
|
562
|
-
.where((0, drizzle_orm_1.eq)(schema_1.chatThreadSessionInvites.id, invite.id));
|
|
563
|
-
logger.info({ threadId, messageId, agentId, sessionId, inviteId: invite.id }, 'Acknowledged invite message');
|
|
564
|
-
}
|
|
565
|
-
else {
|
|
566
|
-
logger.debug({ threadId, messageId, agentId, sessionId }, 'Invite already acknowledged');
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
async startActivity(threadId, agentId, title, options) {
|
|
570
|
-
const announce = options?.announce !== false;
|
|
571
|
-
const now = new Date().toISOString();
|
|
572
|
-
let autoFinishedPrior = false;
|
|
573
|
-
const latest = await this.db
|
|
574
|
-
.select()
|
|
575
|
-
.from(schema_1.chatActivities)
|
|
576
|
-
.where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema_1.chatActivities.threadId, threadId), (0, drizzle_orm_1.eq)(schema_1.chatActivities.agentId, agentId)))
|
|
577
|
-
.orderBy((0, drizzle_orm_1.desc)(schema_1.chatActivities.startedAt))
|
|
578
|
-
.limit(1);
|
|
579
|
-
if (latest.length > 0 && latest[0].status === 'running') {
|
|
580
|
-
await this.db
|
|
581
|
-
.update(schema_1.chatActivities)
|
|
582
|
-
.set({ status: 'auto_finished', finishedAt: now })
|
|
583
|
-
.where((0, drizzle_orm_1.eq)(schema_1.chatActivities.id, latest[0].id));
|
|
584
|
-
autoFinishedPrior = true;
|
|
585
|
-
}
|
|
586
|
-
const startContent = `${title}`;
|
|
587
|
-
let startMessageId = null;
|
|
588
|
-
if (announce) {
|
|
589
|
-
const startMessage = await this.persistMessage(threadId, {
|
|
590
|
-
authorType: 'system',
|
|
591
|
-
content: startContent,
|
|
592
|
-
});
|
|
593
|
-
startMessageId = startMessage.id;
|
|
594
|
-
}
|
|
595
|
-
const activityId = (0, crypto_1.randomUUID)();
|
|
596
|
-
await this.db.insert(schema_1.chatActivities).values({
|
|
597
|
-
id: activityId,
|
|
598
|
-
threadId,
|
|
599
|
-
agentId,
|
|
600
|
-
title,
|
|
601
|
-
status: 'running',
|
|
602
|
-
startedAt: now,
|
|
603
|
-
finishedAt: null,
|
|
604
|
-
startMessageId,
|
|
605
|
-
finishMessageId: null,
|
|
606
|
-
});
|
|
607
|
-
return {
|
|
608
|
-
activityId,
|
|
609
|
-
startMessageId,
|
|
610
|
-
startedAt: now,
|
|
611
|
-
autoFinishedPrior,
|
|
612
|
-
};
|
|
613
|
-
}
|
|
614
|
-
async finishActivity(threadId, agentId, options) {
|
|
615
|
-
const now = new Date().toISOString();
|
|
616
|
-
const running = await this.db
|
|
617
|
-
.select()
|
|
618
|
-
.from(schema_1.chatActivities)
|
|
619
|
-
.where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema_1.chatActivities.threadId, threadId), (0, drizzle_orm_1.eq)(schema_1.chatActivities.agentId, agentId), (0, drizzle_orm_1.eq)(schema_1.chatActivities.status, 'running')))
|
|
620
|
-
.orderBy((0, drizzle_orm_1.desc)(schema_1.chatActivities.startedAt))
|
|
621
|
-
.limit(1);
|
|
622
|
-
if (running.length === 0) {
|
|
623
|
-
throw new error_types_1.ValidationError('No running activity to finish', {
|
|
624
|
-
threadId,
|
|
625
|
-
agentId,
|
|
626
|
-
});
|
|
627
|
-
}
|
|
628
|
-
const current = running[0];
|
|
629
|
-
const status = options?.status ?? 'success';
|
|
630
|
-
let finishMessageId = null;
|
|
631
|
-
if (options?.message && options.message.trim().length > 0) {
|
|
632
|
-
const finishMessage = await this.persistMessage(threadId, {
|
|
633
|
-
authorType: 'system',
|
|
634
|
-
content: options.message,
|
|
635
|
-
});
|
|
636
|
-
finishMessageId = finishMessage.id;
|
|
637
|
-
}
|
|
638
|
-
await this.db
|
|
639
|
-
.update(schema_1.chatActivities)
|
|
640
|
-
.set({ status, finishedAt: now, finishMessageId })
|
|
641
|
-
.where((0, drizzle_orm_1.eq)(schema_1.chatActivities.id, current.id));
|
|
642
|
-
return {
|
|
643
|
-
activityId: current.id,
|
|
644
|
-
finishMessageId,
|
|
645
|
-
startedAt: current.startedAt,
|
|
646
|
-
finishedAt: now,
|
|
647
|
-
status,
|
|
648
|
-
};
|
|
649
|
-
}
|
|
650
|
-
async markMessageAsRead(messageId, agentId) {
|
|
651
|
-
const readAt = new Date().toISOString();
|
|
652
|
-
const existing = await this.db
|
|
653
|
-
.select()
|
|
654
|
-
.from(schema_1.chatMessageReads)
|
|
655
|
-
.where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema_1.chatMessageReads.messageId, messageId), (0, drizzle_orm_1.eq)(schema_1.chatMessageReads.agentId, agentId)))
|
|
656
|
-
.limit(1);
|
|
657
|
-
if (!existing[0]) {
|
|
658
|
-
await this.db.insert(schema_1.chatMessageReads).values({
|
|
659
|
-
messageId,
|
|
660
|
-
agentId,
|
|
661
|
-
readAt,
|
|
662
|
-
});
|
|
663
|
-
logger.info({ messageId, agentId }, 'Marked message as read');
|
|
664
|
-
}
|
|
665
|
-
else {
|
|
666
|
-
logger.debug({ messageId, agentId }, 'Message already marked as read');
|
|
667
|
-
}
|
|
668
|
-
const message = await this.db
|
|
669
|
-
.select({ threadId: schema_1.chatMessages.threadId })
|
|
670
|
-
.from(schema_1.chatMessages)
|
|
671
|
-
.where((0, drizzle_orm_1.eq)(schema_1.chatMessages.id, messageId))
|
|
672
|
-
.limit(1);
|
|
673
|
-
if (message[0]) {
|
|
674
|
-
this.eventEmitter.emit('chat.message.read', {
|
|
675
|
-
threadId: message[0].threadId,
|
|
676
|
-
messageId,
|
|
677
|
-
agentId,
|
|
678
|
-
readAt,
|
|
679
|
-
});
|
|
680
|
-
}
|
|
681
|
-
return { readAt };
|
|
682
|
-
}
|
|
683
|
-
};
|
|
684
|
-
exports.ChatService = ChatService;
|
|
685
|
-
exports.ChatService = ChatService = __decorate([
|
|
686
|
-
(0, common_1.Injectable)(),
|
|
687
|
-
__param(0, (0, common_1.Inject)(db_provider_1.DB_CONNECTION)),
|
|
688
|
-
__metadata("design:paramtypes", [better_sqlite3_1.BetterSQLite3Database,
|
|
689
|
-
event_emitter_1.EventEmitter2,
|
|
690
|
-
chat_settings_service_1.ChatSettingsService,
|
|
691
|
-
chat_session_invite_service_1.ChatSessionInviteService])
|
|
692
|
-
], ChatService);
|
|
693
|
-
//# sourceMappingURL=chat.service.js.map
|