@octo-cyber/ai 0.5.0
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/ai.module.d.ts +3 -0
- package/dist/ai.module.d.ts.map +1 -0
- package/dist/ai.module.js +40 -0
- package/dist/ai.module.js.map +1 -0
- package/dist/cli/adapters/antigravity.adapter.d.ts +29 -0
- package/dist/cli/adapters/antigravity.adapter.d.ts.map +1 -0
- package/dist/cli/adapters/antigravity.adapter.js +170 -0
- package/dist/cli/adapters/antigravity.adapter.js.map +1 -0
- package/dist/cli/adapters/claude-cli.adapter.d.ts +23 -0
- package/dist/cli/adapters/claude-cli.adapter.d.ts.map +1 -0
- package/dist/cli/adapters/claude-cli.adapter.js +79 -0
- package/dist/cli/adapters/claude-cli.adapter.js.map +1 -0
- package/dist/cli/adapters/codex-cli.adapter.d.ts +22 -0
- package/dist/cli/adapters/codex-cli.adapter.d.ts.map +1 -0
- package/dist/cli/adapters/codex-cli.adapter.js +76 -0
- package/dist/cli/adapters/codex-cli.adapter.js.map +1 -0
- package/dist/cli/adapters/detect-cli.d.ts +11 -0
- package/dist/cli/adapters/detect-cli.d.ts.map +1 -0
- package/dist/cli/adapters/detect-cli.js +40 -0
- package/dist/cli/adapters/detect-cli.js.map +1 -0
- package/dist/cli/adapters/gemini-cli.adapter.d.ts +21 -0
- package/dist/cli/adapters/gemini-cli.adapter.d.ts.map +1 -0
- package/dist/cli/adapters/gemini-cli.adapter.js +72 -0
- package/dist/cli/adapters/gemini-cli.adapter.js.map +1 -0
- package/dist/cli/adapters/index.d.ts +4 -0
- package/dist/cli/adapters/index.d.ts.map +1 -0
- package/dist/cli/adapters/index.js +10 -0
- package/dist/cli/adapters/index.js.map +1 -0
- package/dist/cli/cli-executor.service.d.ts +23 -0
- package/dist/cli/cli-executor.service.d.ts.map +1 -0
- package/dist/cli/cli-executor.service.js +150 -0
- package/dist/cli/cli-executor.service.js.map +1 -0
- package/dist/cli/cli-registry.service.d.ts +38 -0
- package/dist/cli/cli-registry.service.d.ts.map +1 -0
- package/dist/cli/cli-registry.service.js +112 -0
- package/dist/cli/cli-registry.service.js.map +1 -0
- package/dist/cli/controllers/ai-cli.controller.d.ts +36 -0
- package/dist/cli/controllers/ai-cli.controller.d.ts.map +1 -0
- package/dist/cli/controllers/ai-cli.controller.js +179 -0
- package/dist/cli/controllers/ai-cli.controller.js.map +1 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +17 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/types.d.ts +131 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js +9 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/cli/workspace.service.d.ts +34 -0
- package/dist/cli/workspace.service.d.ts.map +1 -0
- package/dist/cli/workspace.service.js +194 -0
- package/dist/cli/workspace.service.js.map +1 -0
- package/dist/controllers/agent.controller.d.ts +13 -0
- package/dist/controllers/agent.controller.d.ts.map +1 -0
- package/dist/controllers/agent.controller.js +117 -0
- package/dist/controllers/agent.controller.js.map +1 -0
- package/dist/controllers/capability.controller.d.ts +16 -0
- package/dist/controllers/capability.controller.d.ts.map +1 -0
- package/dist/controllers/capability.controller.js +108 -0
- package/dist/controllers/capability.controller.js.map +1 -0
- package/dist/controllers/client.controller.d.ts +10 -0
- package/dist/controllers/client.controller.d.ts.map +1 -0
- package/dist/controllers/client.controller.js +79 -0
- package/dist/controllers/client.controller.js.map +1 -0
- package/dist/controllers/execution.controller.d.ts +11 -0
- package/dist/controllers/execution.controller.d.ts.map +1 -0
- package/dist/controllers/execution.controller.js +50 -0
- package/dist/controllers/execution.controller.js.map +1 -0
- package/dist/controllers/index.d.ts +5 -0
- package/dist/controllers/index.d.ts.map +1 -0
- package/dist/controllers/index.js +12 -0
- package/dist/controllers/index.js.map +1 -0
- package/dist/entities/agent-binding.entity.d.ts +17 -0
- package/dist/entities/agent-binding.entity.d.ts.map +1 -0
- package/dist/entities/agent-binding.entity.js +64 -0
- package/dist/entities/agent-binding.entity.js.map +1 -0
- package/dist/entities/agent-definition.entity.d.ts +17 -0
- package/dist/entities/agent-definition.entity.d.ts.map +1 -0
- package/dist/entities/agent-definition.entity.js +70 -0
- package/dist/entities/agent-definition.entity.js.map +1 -0
- package/dist/entities/agent-execution.entity.d.ts +23 -0
- package/dist/entities/agent-execution.entity.d.ts.map +1 -0
- package/dist/entities/agent-execution.entity.js +93 -0
- package/dist/entities/agent-execution.entity.js.map +1 -0
- package/dist/entities/agent-instance.entity.d.ts +19 -0
- package/dist/entities/agent-instance.entity.d.ts.map +1 -0
- package/dist/entities/agent-instance.entity.js +76 -0
- package/dist/entities/agent-instance.entity.js.map +1 -0
- package/dist/entities/capability-definition.entity.d.ts +20 -0
- package/dist/entities/capability-definition.entity.d.ts.map +1 -0
- package/dist/entities/capability-definition.entity.js +77 -0
- package/dist/entities/capability-definition.entity.js.map +1 -0
- package/dist/entities/client-registration.entity.d.ts +19 -0
- package/dist/entities/client-registration.entity.d.ts.map +1 -0
- package/dist/entities/client-registration.entity.js +79 -0
- package/dist/entities/client-registration.entity.js.map +1 -0
- package/dist/entities/index.d.ts +7 -0
- package/dist/entities/index.d.ts.map +1 -0
- package/dist/entities/index.js +16 -0
- package/dist/entities/index.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/services/agent.service.d.ts +23 -0
- package/dist/services/agent.service.d.ts.map +1 -0
- package/dist/services/agent.service.js +76 -0
- package/dist/services/agent.service.js.map +1 -0
- package/dist/services/capability-router.service.d.ts +45 -0
- package/dist/services/capability-router.service.d.ts.map +1 -0
- package/dist/services/capability-router.service.js +120 -0
- package/dist/services/capability-router.service.js.map +1 -0
- package/dist/services/client-registration.service.d.ts +27 -0
- package/dist/services/client-registration.service.d.ts.map +1 -0
- package/dist/services/client-registration.service.js +83 -0
- package/dist/services/client-registration.service.js.map +1 -0
- package/dist/services/index.d.ts +5 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +12 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/sync-bridge.service.d.ts +41 -0
- package/dist/services/sync-bridge.service.d.ts.map +1 -0
- package/dist/services/sync-bridge.service.js +118 -0
- package/dist/services/sync-bridge.service.js.map +1 -0
- package/package.json +94 -0
- package/web/components/CliTestDialog.tsx +158 -0
- package/web/index.ts +19 -0
- package/web/manifest.ts +14 -0
- package/web/messages/en-US.json +81 -0
- package/web/messages/zh-CN.json +81 -0
- package/web/pages/AiCliToolsPage.tsx +223 -0
- package/web/pages/WorkspaceSection.tsx +260 -0
- package/web/pages/WorkspacesPage.tsx +397 -0
- package/web/services/ai-cli-service.ts +129 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
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;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.CapabilityRouterService = void 0;
|
|
10
|
+
const core_1 = require("@octo/core");
|
|
11
|
+
/**
|
|
12
|
+
* Routes capability execution requests to the appropriate
|
|
13
|
+
* agent instance running on a capable client.
|
|
14
|
+
*/
|
|
15
|
+
let CapabilityRouterService = class CapabilityRouterService {
|
|
16
|
+
capabilityRepo;
|
|
17
|
+
bindingRepo;
|
|
18
|
+
instanceRepo;
|
|
19
|
+
clientRepo;
|
|
20
|
+
logger = core_1.Container.get(core_1.LoggerService).child('CapabilityRouter');
|
|
21
|
+
setRepositories(capabilityRepo, bindingRepo, instanceRepo, clientRepo) {
|
|
22
|
+
this.capabilityRepo = capabilityRepo;
|
|
23
|
+
this.bindingRepo = bindingRepo;
|
|
24
|
+
this.instanceRepo = instanceRepo;
|
|
25
|
+
this.clientRepo = clientRepo;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Find the best execution target for a capability request.
|
|
29
|
+
*
|
|
30
|
+
* Resolution order:
|
|
31
|
+
* 1. Find capability definition by code
|
|
32
|
+
* 2. Find agent bindings for this capability (ordered by priority)
|
|
33
|
+
* 3. Find online agent instances for the bound agents
|
|
34
|
+
* 4. Match with clients that have the capability enabled
|
|
35
|
+
* 5. Prefer the requested clientId if specified
|
|
36
|
+
*/
|
|
37
|
+
async resolve(request) {
|
|
38
|
+
// 1. Find capability
|
|
39
|
+
const capability = await this.capabilityRepo.findOne({
|
|
40
|
+
where: { code: request.capabilityCode, enabled: true },
|
|
41
|
+
});
|
|
42
|
+
if (!capability) {
|
|
43
|
+
throw core_1.AppError.notFound(`Capability not found: ${request.capabilityCode}`);
|
|
44
|
+
}
|
|
45
|
+
// 2. Find bindings
|
|
46
|
+
const bindings = await this.bindingRepo.find({
|
|
47
|
+
where: { capabilityId: capability.id },
|
|
48
|
+
relations: ['agentDefinition'],
|
|
49
|
+
order: { priority: 'ASC' },
|
|
50
|
+
});
|
|
51
|
+
if (bindings.length === 0) {
|
|
52
|
+
throw core_1.AppError.notFound(`No agent bound to capability: ${request.capabilityCode}`);
|
|
53
|
+
}
|
|
54
|
+
// 3. Find online instances for bound agents
|
|
55
|
+
const definitionIds = bindings.map((b) => b.agentDefinitionId);
|
|
56
|
+
const instances = await this.instanceRepo
|
|
57
|
+
.createQueryBuilder('i')
|
|
58
|
+
.where('i.definitionId IN (:...ids)', { ids: definitionIds })
|
|
59
|
+
.andWhere('i.status = :status', { status: 'IDLE' })
|
|
60
|
+
.andWhere('i.enabled = :enabled', { enabled: true })
|
|
61
|
+
.getMany();
|
|
62
|
+
if (instances.length === 0) {
|
|
63
|
+
throw core_1.AppError.conflict(`No available agent instance for capability: ${request.capabilityCode}`);
|
|
64
|
+
}
|
|
65
|
+
// 4. Match with online clients
|
|
66
|
+
let selectedInstance;
|
|
67
|
+
if (request.preferredClientId) {
|
|
68
|
+
selectedInstance = instances.find((i) => i.clientId === request.preferredClientId);
|
|
69
|
+
}
|
|
70
|
+
if (!selectedInstance) {
|
|
71
|
+
// Find first instance whose client is online with the capability
|
|
72
|
+
for (const instance of instances) {
|
|
73
|
+
const client = await this.clientRepo.findOne({
|
|
74
|
+
where: { clientId: instance.clientId, status: 'ONLINE' },
|
|
75
|
+
});
|
|
76
|
+
if (client && client.enabledCapabilities?.includes(request.capabilityCode)) {
|
|
77
|
+
const matchedClient = client;
|
|
78
|
+
return { capability, agentInstance: instance, client: matchedClient };
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
throw core_1.AppError.conflict(`No online client available for capability: ${request.capabilityCode}`);
|
|
82
|
+
}
|
|
83
|
+
const client = await this.clientRepo.findOne({
|
|
84
|
+
where: { clientId: selectedInstance.clientId },
|
|
85
|
+
});
|
|
86
|
+
if (!client) {
|
|
87
|
+
throw core_1.AppError.conflict(`Client not found: ${selectedInstance.clientId}`);
|
|
88
|
+
}
|
|
89
|
+
return { capability, agentInstance: selectedInstance, client };
|
|
90
|
+
}
|
|
91
|
+
// --- Capability CRUD ---
|
|
92
|
+
async createCapability(data) {
|
|
93
|
+
const cap = this.capabilityRepo.create(data);
|
|
94
|
+
return this.capabilityRepo.save(cap);
|
|
95
|
+
}
|
|
96
|
+
async findAllCapabilities() {
|
|
97
|
+
return this.capabilityRepo.find({ order: { createdAt: 'DESC' } });
|
|
98
|
+
}
|
|
99
|
+
async findCapabilityByCode(code) {
|
|
100
|
+
return this.capabilityRepo.findOne({ where: { code } });
|
|
101
|
+
}
|
|
102
|
+
async updateCapability(id, data) {
|
|
103
|
+
await this.capabilityRepo.update(id, data);
|
|
104
|
+
return this.capabilityRepo.findOne({ where: { id } });
|
|
105
|
+
}
|
|
106
|
+
// --- Bindings ---
|
|
107
|
+
async bindCapabilityToAgent(capabilityId, agentDefinitionId, priority = 0) {
|
|
108
|
+
const binding = this.bindingRepo.create({ capabilityId, agentDefinitionId, priority });
|
|
109
|
+
return this.bindingRepo.save(binding);
|
|
110
|
+
}
|
|
111
|
+
async unbindCapabilityFromAgent(capabilityId, agentDefinitionId) {
|
|
112
|
+
const result = await this.bindingRepo.delete({ capabilityId, agentDefinitionId });
|
|
113
|
+
return (result.affected ?? 0) > 0;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
exports.CapabilityRouterService = CapabilityRouterService;
|
|
117
|
+
exports.CapabilityRouterService = CapabilityRouterService = __decorate([
|
|
118
|
+
(0, core_1.Service)()
|
|
119
|
+
], CapabilityRouterService);
|
|
120
|
+
//# sourceMappingURL=capability-router.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability-router.service.js","sourceRoot":"","sources":["../../src/services/capability-router.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Repository } from '@octo/core';
|
|
2
|
+
import { ClientRegistration } from '../entities/client-registration.entity.js';
|
|
3
|
+
export declare class ClientRegistrationService {
|
|
4
|
+
private clientRepo;
|
|
5
|
+
private logger;
|
|
6
|
+
private heartbeatTimeoutMs;
|
|
7
|
+
setRepository(repo: Repository<ClientRegistration>): void;
|
|
8
|
+
register(data: {
|
|
9
|
+
clientId: string;
|
|
10
|
+
clientName?: string;
|
|
11
|
+
platform?: string;
|
|
12
|
+
enabledCapabilities?: string[];
|
|
13
|
+
userId?: number;
|
|
14
|
+
metadata?: string;
|
|
15
|
+
}): Promise<ClientRegistration>;
|
|
16
|
+
heartbeat(clientId: string): Promise<boolean>;
|
|
17
|
+
unregister(clientId: string): Promise<void>;
|
|
18
|
+
findOnlineClients(): Promise<ClientRegistration[]>;
|
|
19
|
+
findByClientId(clientId: string): Promise<ClientRegistration | null>;
|
|
20
|
+
findAll(): Promise<ClientRegistration[]>;
|
|
21
|
+
/**
|
|
22
|
+
* Mark clients as offline if heartbeat is stale.
|
|
23
|
+
* Should be called periodically.
|
|
24
|
+
*/
|
|
25
|
+
checkStaleClients(): Promise<number>;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=client-registration.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-registration.service.d.ts","sourceRoot":"","sources":["../../src/services/client-registration.service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAG/E,qBACa,yBAAyB;IACpC,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,MAAM,CAA4D;IAC1E,OAAO,CAAC,kBAAkB,CAAU;IAEpC,aAAa,CAAC,IAAI,EAAE,UAAU,CAAC,kBAAkB,CAAC,GAAG,IAAI;IAInD,QAAQ,CAAC,IAAI,EAAE;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;QAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAyBzB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQ7C,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK3C,iBAAiB,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAIlD,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAIpE,OAAO,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAI9C;;;OAGG;IACG,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;CAe3C"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
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;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.ClientRegistrationService = void 0;
|
|
10
|
+
const core_1 = require("@octo/core");
|
|
11
|
+
const client_registration_entity_js_1 = require("../entities/client-registration.entity.js");
|
|
12
|
+
let ClientRegistrationService = class ClientRegistrationService {
|
|
13
|
+
clientRepo;
|
|
14
|
+
logger = core_1.Container.get(core_1.LoggerService).child('ClientRegistration');
|
|
15
|
+
heartbeatTimeoutMs = 60_000;
|
|
16
|
+
setRepository(repo) {
|
|
17
|
+
this.clientRepo = repo;
|
|
18
|
+
}
|
|
19
|
+
async register(data) {
|
|
20
|
+
let client = await this.clientRepo.findOne({ where: { clientId: data.clientId } });
|
|
21
|
+
if (client) {
|
|
22
|
+
// Update existing registration
|
|
23
|
+
client.clientName = data.clientName ?? client.clientName;
|
|
24
|
+
client.platform = data.platform ?? client.platform;
|
|
25
|
+
client.enabledCapabilities = data.enabledCapabilities ?? client.enabledCapabilities;
|
|
26
|
+
client.userId = data.userId ?? client.userId;
|
|
27
|
+
client.metadata = data.metadata ?? client.metadata;
|
|
28
|
+
client.status = 'ONLINE';
|
|
29
|
+
client.lastHeartbeat = new Date();
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
client = this.clientRepo.create({
|
|
33
|
+
...data,
|
|
34
|
+
status: 'ONLINE',
|
|
35
|
+
lastHeartbeat: new Date(),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
const saved = await this.clientRepo.save(client);
|
|
39
|
+
this.logger.info(`Client registered: ${data.clientId}`);
|
|
40
|
+
return saved;
|
|
41
|
+
}
|
|
42
|
+
async heartbeat(clientId) {
|
|
43
|
+
const result = await this.clientRepo.update({ clientId }, { lastHeartbeat: new Date(), status: 'ONLINE' });
|
|
44
|
+
return (result.affected ?? 0) > 0;
|
|
45
|
+
}
|
|
46
|
+
async unregister(clientId) {
|
|
47
|
+
await this.clientRepo.update({ clientId }, { status: 'OFFLINE' });
|
|
48
|
+
this.logger.info(`Client unregistered: ${clientId}`);
|
|
49
|
+
}
|
|
50
|
+
async findOnlineClients() {
|
|
51
|
+
return this.clientRepo.find({ where: { status: 'ONLINE' } });
|
|
52
|
+
}
|
|
53
|
+
async findByClientId(clientId) {
|
|
54
|
+
return this.clientRepo.findOne({ where: { clientId } });
|
|
55
|
+
}
|
|
56
|
+
async findAll() {
|
|
57
|
+
return this.clientRepo.find({ order: { createdAt: 'DESC' } });
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Mark clients as offline if heartbeat is stale.
|
|
61
|
+
* Should be called periodically.
|
|
62
|
+
*/
|
|
63
|
+
async checkStaleClients() {
|
|
64
|
+
const threshold = new Date(Date.now() - this.heartbeatTimeoutMs);
|
|
65
|
+
const result = await this.clientRepo
|
|
66
|
+
.createQueryBuilder()
|
|
67
|
+
.update(client_registration_entity_js_1.ClientRegistration)
|
|
68
|
+
.set({ status: 'OFFLINE' })
|
|
69
|
+
.where('status = :status', { status: 'ONLINE' })
|
|
70
|
+
.andWhere('lastHeartbeat < :threshold', { threshold })
|
|
71
|
+
.execute();
|
|
72
|
+
const affected = result.affected ?? 0;
|
|
73
|
+
if (affected > 0) {
|
|
74
|
+
this.logger.warn(`Marked ${affected} stale clients as OFFLINE`);
|
|
75
|
+
}
|
|
76
|
+
return affected;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
exports.ClientRegistrationService = ClientRegistrationService;
|
|
80
|
+
exports.ClientRegistrationService = ClientRegistrationService = __decorate([
|
|
81
|
+
(0, core_1.Service)()
|
|
82
|
+
], ClientRegistrationService);
|
|
83
|
+
//# sourceMappingURL=client-registration.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-registration.service.js","sourceRoot":"","sources":["../../src/services/client-registration.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { AgentService } from './agent.service.js';
|
|
2
|
+
export { CapabilityRouterService, type CapabilityExecutionRequest, type CapabilityExecutionTarget, } from './capability-router.service.js';
|
|
3
|
+
export { SyncBridgeService } from './sync-bridge.service.js';
|
|
4
|
+
export { ClientRegistrationService } from './client-registration.service.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EACL,uBAAuB,EACvB,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,GAC/B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ClientRegistrationService = exports.SyncBridgeService = exports.CapabilityRouterService = exports.AgentService = void 0;
|
|
4
|
+
var agent_service_js_1 = require("./agent.service.js");
|
|
5
|
+
Object.defineProperty(exports, "AgentService", { enumerable: true, get: function () { return agent_service_js_1.AgentService; } });
|
|
6
|
+
var capability_router_service_js_1 = require("./capability-router.service.js");
|
|
7
|
+
Object.defineProperty(exports, "CapabilityRouterService", { enumerable: true, get: function () { return capability_router_service_js_1.CapabilityRouterService; } });
|
|
8
|
+
var sync_bridge_service_js_1 = require("./sync-bridge.service.js");
|
|
9
|
+
Object.defineProperty(exports, "SyncBridgeService", { enumerable: true, get: function () { return sync_bridge_service_js_1.SyncBridgeService; } });
|
|
10
|
+
var client_registration_service_js_1 = require("./client-registration.service.js");
|
|
11
|
+
Object.defineProperty(exports, "ClientRegistrationService", { enumerable: true, get: function () { return client_registration_service_js_1.ClientRegistrationService; } });
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":";;;AAAA,uDAAkD;AAAzC,gHAAA,YAAY,OAAA;AACrB,+EAIwC;AAHtC,uIAAA,uBAAuB,OAAA;AAIzB,mEAA6D;AAApD,2HAAA,iBAAiB,OAAA;AAC1B,mFAA6E;AAApE,2IAAA,yBAAyB,OAAA"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { AgentExecution } from '../entities/agent-execution.entity.js';
|
|
2
|
+
import type { Repository } from '@octo/core';
|
|
3
|
+
/**
|
|
4
|
+
* Sync Bridge — enables synchronous-style request/response
|
|
5
|
+
* communication with asynchronous agent executions.
|
|
6
|
+
*
|
|
7
|
+
* Pattern: caller sends execution request → waits for completion
|
|
8
|
+
* → agent picks up task → completes → bridge resolves the promise.
|
|
9
|
+
*/
|
|
10
|
+
export declare class SyncBridgeService {
|
|
11
|
+
private pendingRequests;
|
|
12
|
+
private executionRepo;
|
|
13
|
+
private logger;
|
|
14
|
+
private defaultTimeoutMs;
|
|
15
|
+
setRepository(executionRepo: Repository<AgentExecution>): void;
|
|
16
|
+
/**
|
|
17
|
+
* Create an execution and wait for its completion.
|
|
18
|
+
* Returns when the agent completes the execution or timeout.
|
|
19
|
+
*/
|
|
20
|
+
executeAndWait(input: Record<string, unknown>, options?: {
|
|
21
|
+
instanceId?: number;
|
|
22
|
+
capabilityId?: number;
|
|
23
|
+
taskInstanceId?: number;
|
|
24
|
+
timeoutMs?: number;
|
|
25
|
+
}): Promise<Record<string, unknown>>;
|
|
26
|
+
/**
|
|
27
|
+
* Complete an execution — resolves the waiting promise.
|
|
28
|
+
* Called by the agent when execution is done.
|
|
29
|
+
*/
|
|
30
|
+
complete(executionId: number, output: Record<string, unknown>): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Fail an execution — rejects the waiting promise.
|
|
33
|
+
*/
|
|
34
|
+
fail(executionId: number, error: string): Promise<void>;
|
|
35
|
+
/** Get count of pending bridge requests. */
|
|
36
|
+
get pendingCount(): number;
|
|
37
|
+
/** Clean up all pending requests on shutdown. */
|
|
38
|
+
destroy(): void;
|
|
39
|
+
private calculateDuration;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=sync-bridge.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-bridge.service.d.ts","sourceRoot":"","sources":["../../src/services/sync-bridge.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAS7C;;;;;;GAMG;AACH,qBACa,iBAAiB;IAC5B,OAAO,CAAC,eAAe,CAAqC;IAC5D,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,MAAM,CAAoD;IAClE,OAAO,CAAC,gBAAgB,CAAU;IAElC,aAAa,CAAC,aAAa,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,IAAI;IAI9D;;;OAGG;IACG,cAAc,CAClB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,CAAC,EAAE;QACR,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GACA,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IA+BnC;;;OAGG;IACG,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBnF;;OAEG;IACG,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB7D,4CAA4C;IAC5C,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,iDAAiD;IACjD,OAAO,IAAI,IAAI;YAQD,iBAAiB;CAKhC"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
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;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.SyncBridgeService = void 0;
|
|
10
|
+
const core_1 = require("@octo/core");
|
|
11
|
+
/**
|
|
12
|
+
* Sync Bridge — enables synchronous-style request/response
|
|
13
|
+
* communication with asynchronous agent executions.
|
|
14
|
+
*
|
|
15
|
+
* Pattern: caller sends execution request → waits for completion
|
|
16
|
+
* → agent picks up task → completes → bridge resolves the promise.
|
|
17
|
+
*/
|
|
18
|
+
let SyncBridgeService = class SyncBridgeService {
|
|
19
|
+
pendingRequests = new Map();
|
|
20
|
+
executionRepo;
|
|
21
|
+
logger = core_1.Container.get(core_1.LoggerService).child('SyncBridge');
|
|
22
|
+
defaultTimeoutMs = 60_000;
|
|
23
|
+
setRepository(executionRepo) {
|
|
24
|
+
this.executionRepo = executionRepo;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Create an execution and wait for its completion.
|
|
28
|
+
* Returns when the agent completes the execution or timeout.
|
|
29
|
+
*/
|
|
30
|
+
async executeAndWait(input, options) {
|
|
31
|
+
const execution = this.executionRepo.create({
|
|
32
|
+
status: 'PENDING',
|
|
33
|
+
input,
|
|
34
|
+
instanceId: options?.instanceId ?? null,
|
|
35
|
+
capabilityId: options?.capabilityId ?? null,
|
|
36
|
+
taskInstanceId: options?.taskInstanceId ?? null,
|
|
37
|
+
});
|
|
38
|
+
const saved = await this.executionRepo.save(execution);
|
|
39
|
+
const bridgeKey = `exec:${saved.id}`;
|
|
40
|
+
const timeoutMs = options?.timeoutMs ?? this.defaultTimeoutMs;
|
|
41
|
+
return new Promise((resolve, reject) => {
|
|
42
|
+
const timer = setTimeout(() => {
|
|
43
|
+
this.pendingRequests.delete(bridgeKey);
|
|
44
|
+
this.executionRepo.update(saved.id, { status: 'TIMEOUT' }).catch(() => { });
|
|
45
|
+
reject(core_1.AppError.conflict(`SyncBridge timeout after ${timeoutMs}ms for execution ${saved.id}`));
|
|
46
|
+
}, timeoutMs);
|
|
47
|
+
this.pendingRequests.set(bridgeKey, {
|
|
48
|
+
resolve,
|
|
49
|
+
reject,
|
|
50
|
+
timer,
|
|
51
|
+
executionId: saved.id,
|
|
52
|
+
});
|
|
53
|
+
this.logger.debug(`SyncBridge waiting for execution ${saved.id} (timeout: ${timeoutMs}ms)`);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Complete an execution — resolves the waiting promise.
|
|
58
|
+
* Called by the agent when execution is done.
|
|
59
|
+
*/
|
|
60
|
+
async complete(executionId, output) {
|
|
61
|
+
const bridgeKey = `exec:${executionId}`;
|
|
62
|
+
const pending = this.pendingRequests.get(bridgeKey);
|
|
63
|
+
await this.executionRepo.update(executionId, {
|
|
64
|
+
status: 'COMPLETED',
|
|
65
|
+
output: output,
|
|
66
|
+
completedAt: new Date(),
|
|
67
|
+
durationMs: await this.calculateDuration(executionId),
|
|
68
|
+
});
|
|
69
|
+
if (pending) {
|
|
70
|
+
clearTimeout(pending.timer);
|
|
71
|
+
this.pendingRequests.delete(bridgeKey);
|
|
72
|
+
pending.resolve(output);
|
|
73
|
+
this.logger.debug(`SyncBridge resolved execution ${executionId}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Fail an execution — rejects the waiting promise.
|
|
78
|
+
*/
|
|
79
|
+
async fail(executionId, error) {
|
|
80
|
+
const bridgeKey = `exec:${executionId}`;
|
|
81
|
+
const pending = this.pendingRequests.get(bridgeKey);
|
|
82
|
+
await this.executionRepo.update(executionId, {
|
|
83
|
+
status: 'FAILED',
|
|
84
|
+
error,
|
|
85
|
+
completedAt: new Date(),
|
|
86
|
+
durationMs: await this.calculateDuration(executionId),
|
|
87
|
+
});
|
|
88
|
+
if (pending) {
|
|
89
|
+
clearTimeout(pending.timer);
|
|
90
|
+
this.pendingRequests.delete(bridgeKey);
|
|
91
|
+
pending.reject(new Error(error));
|
|
92
|
+
this.logger.debug(`SyncBridge rejected execution ${executionId}: ${error}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/** Get count of pending bridge requests. */
|
|
96
|
+
get pendingCount() {
|
|
97
|
+
return this.pendingRequests.size;
|
|
98
|
+
}
|
|
99
|
+
/** Clean up all pending requests on shutdown. */
|
|
100
|
+
destroy() {
|
|
101
|
+
for (const [key, pending] of this.pendingRequests) {
|
|
102
|
+
clearTimeout(pending.timer);
|
|
103
|
+
pending.reject(new Error('SyncBridge shutting down'));
|
|
104
|
+
this.pendingRequests.delete(key);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
async calculateDuration(executionId) {
|
|
108
|
+
const execution = await this.executionRepo.findOne({ where: { id: executionId } });
|
|
109
|
+
if (!execution)
|
|
110
|
+
return 0;
|
|
111
|
+
return Date.now() - execution.createdAt.getTime();
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
exports.SyncBridgeService = SyncBridgeService;
|
|
115
|
+
exports.SyncBridgeService = SyncBridgeService = __decorate([
|
|
116
|
+
(0, core_1.Service)()
|
|
117
|
+
], SyncBridgeService);
|
|
118
|
+
//# sourceMappingURL=sync-bridge.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-bridge.service.js","sourceRoot":"","sources":["../../src/services/sync-bridge.service.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@octo-cyber/ai",
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "Octo AI module — Agent + Capability + SyncBridge + client registration",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./web": {
|
|
14
|
+
"types": "./web/index.ts",
|
|
15
|
+
"import": "./web/index.ts",
|
|
16
|
+
"default": "./web/index.ts"
|
|
17
|
+
},
|
|
18
|
+
"./web/pages/*": {
|
|
19
|
+
"types": "./web/pages/*.tsx",
|
|
20
|
+
"import": "./web/pages/*.tsx",
|
|
21
|
+
"default": "./web/pages/*.tsx"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@octo-cyber/core": "^0.5.0",
|
|
26
|
+
"@octo-cyber/task": "^0.5.0",
|
|
27
|
+
"@octo-cyber/auth": "^0.5.0"
|
|
28
|
+
},
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"react": "^19.0.0",
|
|
31
|
+
"react-dom": "^19.0.0",
|
|
32
|
+
"next": "^16.0.0",
|
|
33
|
+
"next-intl": "^4.0.0",
|
|
34
|
+
"lucide-react": ">=0.400.0",
|
|
35
|
+
"react-hook-form": "^7.0.0",
|
|
36
|
+
"@hookform/resolvers": "^5.0.0",
|
|
37
|
+
"@tanstack/react-table": "^8.0.0",
|
|
38
|
+
"zod": "^3.0.0",
|
|
39
|
+
"sonner": "^2.0.0",
|
|
40
|
+
"@octo-cyber/ui": "^0.5.0"
|
|
41
|
+
},
|
|
42
|
+
"peerDependenciesMeta": {
|
|
43
|
+
"@octo-cyber/ui": {
|
|
44
|
+
"optional": true
|
|
45
|
+
},
|
|
46
|
+
"react": {
|
|
47
|
+
"optional": true
|
|
48
|
+
},
|
|
49
|
+
"react-dom": {
|
|
50
|
+
"optional": true
|
|
51
|
+
},
|
|
52
|
+
"next": {
|
|
53
|
+
"optional": true
|
|
54
|
+
},
|
|
55
|
+
"next-intl": {
|
|
56
|
+
"optional": true
|
|
57
|
+
},
|
|
58
|
+
"lucide-react": {
|
|
59
|
+
"optional": true
|
|
60
|
+
},
|
|
61
|
+
"react-hook-form": {
|
|
62
|
+
"optional": true
|
|
63
|
+
},
|
|
64
|
+
"@hookform/resolvers": {
|
|
65
|
+
"optional": true
|
|
66
|
+
},
|
|
67
|
+
"@tanstack/react-table": {
|
|
68
|
+
"optional": true
|
|
69
|
+
},
|
|
70
|
+
"zod": {
|
|
71
|
+
"optional": true
|
|
72
|
+
},
|
|
73
|
+
"sonner": {
|
|
74
|
+
"optional": true
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"devDependencies": {
|
|
78
|
+
"@types/react": "^19",
|
|
79
|
+
"@types/react-dom": "^19",
|
|
80
|
+
"typescript": "^5.8.0",
|
|
81
|
+
"vitest": "^3.0.0"
|
|
82
|
+
},
|
|
83
|
+
"files": [
|
|
84
|
+
"dist",
|
|
85
|
+
"web"
|
|
86
|
+
],
|
|
87
|
+
"license": "MIT",
|
|
88
|
+
"scripts": {
|
|
89
|
+
"build": "tsc -p tsconfig.build.json",
|
|
90
|
+
"dev": "tsc -p tsconfig.build.json --watch",
|
|
91
|
+
"test": "vitest run",
|
|
92
|
+
"typecheck": "tsc --noEmit"
|
|
93
|
+
}
|
|
94
|
+
}
|