aimeat 1.7.0 → 1.9.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/.env.example +4 -1
- package/dist/locales/en.json +573 -10
- package/dist/locales/fi.json +572 -9
- package/dist/public/css/views/admin-agent-integration.css +304 -0
- package/dist/public/css/views/agents-detail.css +1697 -120
- package/dist/public/css/views/profile.css +22 -2
- package/dist/public/css/views/public-knowledge-viewer.css +479 -0
- package/dist/public/js/i18n.js +9 -3
- package/dist/public/js/services/admin-agent-integration.js +52 -0
- package/dist/public/js/services/agent-integration.js +80 -0
- package/dist/public/js/services/agent-messages.js +3 -1
- package/dist/public/js/services/generator-spec-validate.js +23 -0
- package/dist/public/js/services/memory.js +39 -0
- package/dist/public/lib/live-updates.js +9 -4
- package/dist/public/llms-template.txt +106 -0
- package/dist/public/spa.html +7 -2
- package/dist/public/views/admin/agent-integration-tab.js +390 -0
- package/dist/public/views/admin/federation-tab.js +5 -5
- package/dist/public/views/admin/prompts-tab.js +9 -10
- package/dist/public/views/admin.js +2 -0
- package/dist/public/views/profile/access-tab.js +18 -0
- package/dist/public/views/profile/agents/agent-card.js +396 -0
- package/dist/public/views/profile/agents/shared-board.js +97 -0
- package/dist/public/views/profile/agents/state-detector.js +62 -0
- package/dist/public/views/profile/agents/tab-activity.js +232 -0
- package/dist/public/views/profile/agents/tab-agent-config.js +199 -0
- package/dist/public/views/profile/agents/tab-data-access.js +304 -0
- package/dist/public/views/profile/agents/tab-directives.js +178 -0
- package/dist/public/views/profile/agents/tab-integration.js +505 -0
- package/dist/public/views/profile/agents/tab-messages.js +278 -0
- package/dist/public/views/profile/agents/tab-services.js +17 -0
- package/dist/public/views/profile/agents/tab-tasks.js +17 -0
- package/dist/public/views/profile/agents-messages-subtab.js +12 -10
- package/dist/public/views/profile/agents-services-subtab.js +17 -11
- package/dist/public/views/profile/agents-tab.js +159 -255
- package/dist/public/views/profile/agents-task-builder.js +403 -0
- package/dist/public/views/profile/agents-tasks-subtab.js +186 -140
- package/dist/public/views/profile/generator-detail.js +8 -1
- package/dist/public/views/profile/memory-tab.js +371 -7
- package/dist/public/views/profile/wallet-tab.js +14 -0
- package/dist/public/views/public-knowledge-viewer.js +650 -0
- package/dist/src/auth/middleware.d.ts.map +1 -1
- package/dist/src/auth/middleware.js +17 -0
- package/dist/src/auth/middleware.js.map +1 -1
- package/dist/src/config.d.ts +1 -0
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +1 -0
- package/dist/src/config.js.map +1 -1
- package/dist/src/middleware/readiness-gate.d.ts +18 -0
- package/dist/src/middleware/readiness-gate.d.ts.map +1 -0
- package/dist/src/middleware/readiness-gate.js +50 -0
- package/dist/src/middleware/readiness-gate.js.map +1 -0
- package/dist/src/models/agent-capabilities-schemas.d.ts +3 -0
- package/dist/src/models/agent-capabilities-schemas.d.ts.map +1 -1
- package/dist/src/models/agent-capabilities-schemas.js +3 -0
- package/dist/src/models/agent-capabilities-schemas.js.map +1 -1
- package/dist/src/models/agent-directives-schemas.d.ts +12 -0
- package/dist/src/models/agent-directives-schemas.d.ts.map +1 -1
- package/dist/src/models/agent-directives-schemas.js +7 -0
- package/dist/src/models/agent-directives-schemas.js.map +1 -1
- package/dist/src/models/agent-onboarding-schemas.d.ts +45 -0
- package/dist/src/models/agent-onboarding-schemas.d.ts.map +1 -0
- package/dist/src/models/agent-onboarding-schemas.js +91 -0
- package/dist/src/models/agent-onboarding-schemas.js.map +1 -0
- package/dist/src/models/webhook-schemas.d.ts +266 -0
- package/dist/src/models/webhook-schemas.d.ts.map +1 -0
- package/dist/src/models/webhook-schemas.js +137 -0
- package/dist/src/models/webhook-schemas.js.map +1 -0
- package/dist/src/routes/admin-agent-integration.d.ts +24 -0
- package/dist/src/routes/admin-agent-integration.d.ts.map +1 -0
- package/dist/src/routes/admin-agent-integration.js +186 -0
- package/dist/src/routes/admin-agent-integration.js.map +1 -0
- package/dist/src/routes/admin-monitoring.js +12 -7
- package/dist/src/routes/admin-monitoring.js.map +1 -1
- package/dist/src/routes/agent-activity.d.ts.map +1 -1
- package/dist/src/routes/agent-activity.js +17 -0
- package/dist/src/routes/agent-activity.js.map +1 -1
- package/dist/src/routes/agent-capabilities.d.ts +1 -0
- package/dist/src/routes/agent-capabilities.d.ts.map +1 -1
- package/dist/src/routes/agent-capabilities.js +9 -0
- package/dist/src/routes/agent-capabilities.js.map +1 -1
- package/dist/src/routes/agent-directives.d.ts +5 -1
- package/dist/src/routes/agent-directives.d.ts.map +1 -1
- package/dist/src/routes/agent-directives.js +74 -20
- package/dist/src/routes/agent-directives.js.map +1 -1
- package/dist/src/routes/agent-integration.d.ts +1 -0
- package/dist/src/routes/agent-integration.d.ts.map +1 -1
- package/dist/src/routes/agent-integration.js +128 -11
- package/dist/src/routes/agent-integration.js.map +1 -1
- package/dist/src/routes/agent-messages.d.ts +5 -1
- package/dist/src/routes/agent-messages.d.ts.map +1 -1
- package/dist/src/routes/agent-messages.js +20 -1
- package/dist/src/routes/agent-messages.js.map +1 -1
- package/dist/src/routes/agent-onboarding.d.ts +23 -0
- package/dist/src/routes/agent-onboarding.d.ts.map +1 -0
- package/dist/src/routes/agent-onboarding.js +374 -0
- package/dist/src/routes/agent-onboarding.js.map +1 -0
- package/dist/src/routes/agent-skill-bundle.d.ts +16 -0
- package/dist/src/routes/agent-skill-bundle.d.ts.map +1 -0
- package/dist/src/routes/agent-skill-bundle.js +133 -0
- package/dist/src/routes/agent-skill-bundle.js.map +1 -0
- package/dist/src/routes/agent-tasks.d.ts +8 -1
- package/dist/src/routes/agent-tasks.d.ts.map +1 -1
- package/dist/src/routes/agent-tasks.js +192 -14
- package/dist/src/routes/agent-tasks.js.map +1 -1
- package/dist/src/routes/agent-telemetry.d.ts +15 -0
- package/dist/src/routes/agent-telemetry.d.ts.map +1 -0
- package/dist/src/routes/agent-telemetry.js +99 -0
- package/dist/src/routes/agent-telemetry.js.map +1 -0
- package/dist/src/routes/agent-webhook.d.ts +18 -0
- package/dist/src/routes/agent-webhook.d.ts.map +1 -0
- package/dist/src/routes/agent-webhook.js +243 -0
- package/dist/src/routes/agent-webhook.js.map +1 -0
- package/dist/src/routes/agents.d.ts.map +1 -1
- package/dist/src/routes/agents.js +203 -4
- package/dist/src/routes/agents.js.map +1 -1
- package/dist/src/routes/auth.d.ts.map +1 -1
- package/dist/src/routes/auth.js +45 -2
- package/dist/src/routes/auth.js.map +1 -1
- package/dist/src/routes/federation-auth.d.ts.map +1 -1
- package/dist/src/routes/federation-auth.js +3 -1
- package/dist/src/routes/federation-auth.js.map +1 -1
- package/dist/src/routes/federation-peer.d.ts.map +1 -1
- package/dist/src/routes/federation-peer.js +11 -2
- package/dist/src/routes/federation-peer.js.map +1 -1
- package/dist/src/routes/federation-sync.d.ts +1 -0
- package/dist/src/routes/federation-sync.d.ts.map +1 -1
- package/dist/src/routes/federation-sync.js +29 -0
- package/dist/src/routes/federation-sync.js.map +1 -1
- package/dist/src/routes/ghii.d.ts.map +1 -1
- package/dist/src/routes/ghii.js +42 -5
- package/dist/src/routes/ghii.js.map +1 -1
- package/dist/src/routes/knowledge.d.ts.map +1 -1
- package/dist/src/routes/knowledge.js +19 -7
- package/dist/src/routes/knowledge.js.map +1 -1
- package/dist/src/routes/memory.d.ts +9 -0
- package/dist/src/routes/memory.d.ts.map +1 -1
- package/dist/src/routes/memory.js +307 -12
- package/dist/src/routes/memory.js.map +1 -1
- package/dist/src/routes/portal.d.ts.map +1 -1
- package/dist/src/routes/portal.js +1 -0
- package/dist/src/routes/portal.js.map +1 -1
- package/dist/src/routes/prompts.d.ts +1 -0
- package/dist/src/routes/prompts.d.ts.map +1 -1
- package/dist/src/routes/prompts.js +40 -1
- package/dist/src/routes/prompts.js.map +1 -1
- package/dist/src/routes/sharing-groups.d.ts.map +1 -1
- package/dist/src/routes/sharing-groups.js +8 -2
- package/dist/src/routes/sharing-groups.js.map +1 -1
- package/dist/src/routes/wallet.d.ts.map +1 -1
- package/dist/src/routes/wallet.js +2 -0
- package/dist/src/routes/wallet.js.map +1 -1
- package/dist/src/server-bootstrap/routes-loader.d.ts.map +1 -1
- package/dist/src/server-bootstrap/routes-loader.js +47 -3
- package/dist/src/server-bootstrap/routes-loader.js.map +1 -1
- package/dist/src/services/config-schema.d.ts.map +1 -1
- package/dist/src/services/config-schema.js +2 -1
- package/dist/src/services/config-schema.js.map +1 -1
- package/dist/src/services/core-jobs.d.ts.map +1 -1
- package/dist/src/services/core-jobs.js +3 -2
- package/dist/src/services/core-jobs.js.map +1 -1
- package/dist/src/services/federation-helpers.d.ts +1 -0
- package/dist/src/services/federation-helpers.d.ts.map +1 -1
- package/dist/src/services/federation-helpers.js +1 -1
- package/dist/src/services/federation-helpers.js.map +1 -1
- package/dist/src/services/generator-autopilot.d.ts.map +1 -1
- package/dist/src/services/generator-autopilot.js +125 -26
- package/dist/src/services/generator-autopilot.js.map +1 -1
- package/dist/src/services/generator-prompts/index.d.ts +1 -1
- package/dist/src/services/generator-prompts/index.d.ts.map +1 -1
- package/dist/src/services/generator-prompts/index.js +1 -1
- package/dist/src/services/generator-prompts/index.js.map +1 -1
- package/dist/src/services/generator-prompts/spec-validate.d.ts +1 -0
- package/dist/src/services/generator-prompts/spec-validate.d.ts.map +1 -1
- package/dist/src/services/generator-prompts/spec-validate.js +20 -0
- package/dist/src/services/generator-prompts/spec-validate.js.map +1 -1
- package/dist/src/services/generator-prompts/validate.d.ts +7 -1
- package/dist/src/services/generator-prompts/validate.d.ts.map +1 -1
- package/dist/src/services/generator-prompts/validate.js +70 -0
- package/dist/src/services/generator-prompts/validate.js.map +1 -1
- package/dist/src/services/onboarding-validator.d.ts +22 -0
- package/dist/src/services/onboarding-validator.d.ts.map +1 -0
- package/dist/src/services/onboarding-validator.js +202 -0
- package/dist/src/services/onboarding-validator.js.map +1 -0
- package/dist/src/services/platform-detector.d.ts +27 -0
- package/dist/src/services/platform-detector.d.ts.map +1 -0
- package/dist/src/services/platform-detector.js +73 -0
- package/dist/src/services/platform-detector.js.map +1 -0
- package/dist/src/services/prompt-defaults.d.ts +1 -0
- package/dist/src/services/prompt-defaults.d.ts.map +1 -1
- package/dist/src/services/prompt-defaults.js +875 -47
- package/dist/src/services/prompt-defaults.js.map +1 -1
- package/dist/src/services/prompt-seeder.js +1 -1
- package/dist/src/services/prompt-seeder.js.map +1 -1
- package/dist/src/services/readiness-scorer.d.ts +34 -0
- package/dist/src/services/readiness-scorer.d.ts.map +1 -0
- package/dist/src/services/readiness-scorer.js +87 -0
- package/dist/src/services/readiness-scorer.js.map +1 -0
- package/dist/src/services/skill-bundle/generator.d.ts +17 -0
- package/dist/src/services/skill-bundle/generator.d.ts.map +1 -0
- package/dist/src/services/skill-bundle/generator.js +387 -0
- package/dist/src/services/skill-bundle/generator.js.map +1 -0
- package/dist/src/services/skill-bundle/generic-adapter.d.ts +16 -0
- package/dist/src/services/skill-bundle/generic-adapter.d.ts.map +1 -0
- package/dist/src/services/skill-bundle/generic-adapter.js +96 -0
- package/dist/src/services/skill-bundle/generic-adapter.js.map +1 -0
- package/dist/src/services/skill-bundle/hermes-adapter.d.ts +25 -0
- package/dist/src/services/skill-bundle/hermes-adapter.d.ts.map +1 -0
- package/dist/src/services/skill-bundle/hermes-adapter.js +302 -0
- package/dist/src/services/skill-bundle/hermes-adapter.js.map +1 -0
- package/dist/src/services/skill-bundle/types.d.ts +54 -0
- package/dist/src/services/skill-bundle/types.d.ts.map +1 -0
- package/dist/src/services/skill-bundle/types.js +8 -0
- package/dist/src/services/skill-bundle/types.js.map +1 -0
- package/dist/src/services/task-stall-detector.d.ts +10 -2
- package/dist/src/services/task-stall-detector.d.ts.map +1 -1
- package/dist/src/services/task-stall-detector.js +34 -5
- package/dist/src/services/task-stall-detector.js.map +1 -1
- package/dist/src/services/webhook-dispatcher.d.ts +71 -0
- package/dist/src/services/webhook-dispatcher.d.ts.map +1 -0
- package/dist/src/services/webhook-dispatcher.js +259 -0
- package/dist/src/services/webhook-dispatcher.js.map +1 -0
- package/dist/src/storage/interface.d.ts +82 -2
- package/dist/src/storage/interface.d.ts.map +1 -1
- package/dist/src/storage/providers/mongodb/index.d.ts +20 -1
- package/dist/src/storage/providers/mongodb/index.d.ts.map +1 -1
- package/dist/src/storage/providers/mongodb/index.js +254 -3
- package/dist/src/storage/providers/mongodb/index.js.map +1 -1
- package/dist/src/storage/providers/sqlite/index.d.ts +18 -1
- package/dist/src/storage/providers/sqlite/index.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/index.js +173 -4
- package/dist/src/storage/providers/sqlite/index.js.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/agent-directives.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/agent-directives.js +8 -4
- package/dist/src/storage/providers/sqlite/repos/agent-directives.js.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/agent.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/agent.js +25 -4
- package/dist/src/storage/providers/sqlite/repos/agent.js.map +1 -1
- package/dist/src/storage/providers/sqlite/schema.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/schema.js +73 -1
- package/dist/src/storage/providers/sqlite/schema.js.map +1 -1
- package/dist/src/storage/repositories/agent-onboarding.repository.d.ts +16 -0
- package/dist/src/storage/repositories/agent-onboarding.repository.d.ts.map +1 -0
- package/dist/src/storage/repositories/agent-onboarding.repository.js +8 -0
- package/dist/src/storage/repositories/agent-onboarding.repository.js.map +1 -0
- package/dist/src/storage/repositories/agent-webhook.repository.d.ts +21 -0
- package/dist/src/storage/repositories/agent-webhook.repository.d.ts.map +1 -0
- package/dist/src/storage/repositories/agent-webhook.repository.js +2 -0
- package/dist/src/storage/repositories/agent-webhook.repository.js.map +1 -0
- package/dist/src/storage/repositories/agent.repository.d.ts +1 -0
- package/dist/src/storage/repositories/agent.repository.d.ts.map +1 -1
- package/dist/src/storage/repositories/index.d.ts +2 -0
- package/dist/src/storage/repositories/index.d.ts.map +1 -1
- package/dist/src/utils/env-config.d.ts.map +1 -1
- package/dist/src/utils/env-config.js +7 -1
- package/dist/src/utils/env-config.js.map +1 -1
- package/dist/src/utils/url-validator.d.ts.map +1 -1
- package/dist/src/utils/url-validator.js +3 -0
- package/dist/src/utils/url-validator.js.map +1 -1
- package/package.json +1 -1
- package/prisma/schema.prisma +67 -7
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* - validateDataApiSpec: structural validation of data API spec JSON
|
|
9
9
|
* - validateComponentSpec: structural validation of component spec JSON
|
|
10
10
|
* - validateAppDomainSpec: structural validation of app-domain spec JSON
|
|
11
|
+
* - validateAppSpec: structural validation of app (HTML page) spec JSON
|
|
11
12
|
* - validateSpecAgainstProbe: compare spec declarations against probe results
|
|
12
13
|
* @usage
|
|
13
14
|
* import { validateExtensionSpec, validateSpecAgainstProbe } from '/js/services/generator-spec-validate.js';
|
|
@@ -122,6 +123,28 @@ export function validateAppDomainSpec(spec) {
|
|
|
122
123
|
return { valid: errors.length === 0, errors };
|
|
123
124
|
}
|
|
124
125
|
|
|
126
|
+
/**
|
|
127
|
+
* Validate that an app (HTML page) spec has required structure.
|
|
128
|
+
* @param {object} spec - Parsed app spec JSON
|
|
129
|
+
* @returns {{ valid: boolean, errors: string[] }}
|
|
130
|
+
*/
|
|
131
|
+
export function validateAppSpec(spec) {
|
|
132
|
+
const errors = [];
|
|
133
|
+
if (!spec) return { valid: false, errors: ['Spec is null or undefined'] };
|
|
134
|
+
|
|
135
|
+
if (!spec.name) errors.push('Missing spec.name');
|
|
136
|
+
if (spec.name && !/^[a-z0-9]+(-[a-z0-9]+)*$/.test(spec.name)) {
|
|
137
|
+
errors.push(`spec.name "${spec.name}" must be ASCII kebab-case`);
|
|
138
|
+
}
|
|
139
|
+
if (!spec.title) errors.push('Missing spec.title');
|
|
140
|
+
if (!spec.appDomainLib) errors.push('Missing spec.appDomainLib — must reference the app-domain cortex libName');
|
|
141
|
+
if (!Array.isArray(spec.cortexDependencies) || spec.cortexDependencies.length === 0) {
|
|
142
|
+
errors.push('Missing or empty spec.cortexDependencies — must list all cortex registeredAs names');
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return { valid: errors.length === 0, errors };
|
|
146
|
+
}
|
|
147
|
+
|
|
125
148
|
/**
|
|
126
149
|
* Compare extension spec against actual probe results.
|
|
127
150
|
* SPEC IS KING: if probe response doesn't match spec, the CODE is wrong.
|
|
@@ -123,3 +123,42 @@ export async function pullFromHome(key) {
|
|
|
123
123
|
export async function pushToHome(key) {
|
|
124
124
|
return apiPost('/v1/memory/push-home', { key });
|
|
125
125
|
}
|
|
126
|
+
|
|
127
|
+
/** List memory entries on the home node (federated sessions). */
|
|
128
|
+
export async function listHomeMemories() {
|
|
129
|
+
const resp = await apiPost('/v1/memory/list-home', {});
|
|
130
|
+
return resp?.data?.entries || [];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** List memory entries on a remote peer node (home sessions). */
|
|
134
|
+
export async function listRemoteMemories(peerNodeId) {
|
|
135
|
+
const resp = await apiPost('/v1/memory/list-remote', { peer_node_id: peerNodeId });
|
|
136
|
+
return resp?.data?.entries || [];
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** Pull a memory entry from a remote peer node (home sessions). */
|
|
140
|
+
export async function pullFromRemote(peerNodeId, key) {
|
|
141
|
+
return apiPost('/v1/memory/pull-remote', { peer_node_id: peerNodeId, key });
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** Discover public memory entries from other users on this node. */
|
|
145
|
+
export async function discoverPublicMemories(opts = {}) {
|
|
146
|
+
const params = new URLSearchParams();
|
|
147
|
+
if (opts.prefix) params.set('prefix', opts.prefix);
|
|
148
|
+
if (opts.owner) params.set('owner', opts.owner);
|
|
149
|
+
if (opts.q) params.set('q', opts.q);
|
|
150
|
+
if (opts.limit) params.set('limit', String(opts.limit));
|
|
151
|
+
if (opts.offset) params.set('offset', String(opts.offset));
|
|
152
|
+
const qs = params.toString();
|
|
153
|
+
const data = await apiGet('/v1/memory/discover' + (qs ? '?' + qs : ''));
|
|
154
|
+
return data?.data || { items: [], total: 0 };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** Copy a public memory entry from another user to your own memory. */
|
|
158
|
+
export async function copyPublicMemory(sourceGaii, key, visibility) {
|
|
159
|
+
return apiPost('/v1/memory/copy', {
|
|
160
|
+
source_gaii: sourceGaii,
|
|
161
|
+
key,
|
|
162
|
+
visibility: visibility || 'private',
|
|
163
|
+
});
|
|
164
|
+
}
|
|
@@ -29,7 +29,12 @@ async function _open() {
|
|
|
29
29
|
method: 'POST',
|
|
30
30
|
headers: { 'Authorization': `Bearer ${jwt}` },
|
|
31
31
|
});
|
|
32
|
-
if (!resp.ok)
|
|
32
|
+
if (!resp.ok) {
|
|
33
|
+
console.warn('[SSE] Ticket request failed:', resp.status);
|
|
34
|
+
reconnectTimer = setTimeout(() => { if (refCount > 0) _open(); }, reconnectDelay);
|
|
35
|
+
reconnectDelay = Math.min(reconnectDelay * 2, MAX_RECONNECT_DELAY);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
33
38
|
const body = await resp.json();
|
|
34
39
|
const ticket = body.data.ticket;
|
|
35
40
|
|
|
@@ -39,12 +44,12 @@ async function _open() {
|
|
|
39
44
|
reconnectDelay = 5000; // reset on successful connection
|
|
40
45
|
};
|
|
41
46
|
|
|
42
|
-
es.onmessage = () => {
|
|
43
|
-
reconnectDelay = 5000;
|
|
47
|
+
es.onmessage = (event) => {
|
|
48
|
+
reconnectDelay = 5000;
|
|
44
49
|
clearTimeout(debounceTimer);
|
|
45
50
|
debounceTimer = setTimeout(() => {
|
|
46
51
|
listeners.forEach(fn => fn());
|
|
47
|
-
},
|
|
52
|
+
}, 500);
|
|
48
53
|
};
|
|
49
54
|
|
|
50
55
|
es.onerror = () => {
|
|
@@ -801,6 +801,112 @@ On approval (HTTP 200):
|
|
|
801
801
|
- `gaii` — your identity on this node
|
|
802
802
|
- `token` — use for all API calls: `Authorization: Bearer <token>`
|
|
803
803
|
|
|
804
|
+
## Agent API Quick Reference
|
|
805
|
+
|
|
806
|
+
All agent endpoints use `/v1/agents/me/` which resolves to your agent name. Header: `Authorization: Bearer <token>`
|
|
807
|
+
|
|
808
|
+
### Capabilities
|
|
809
|
+
|
|
810
|
+
```
|
|
811
|
+
PUT /v1/agents/me/capabilities
|
|
812
|
+
{
|
|
813
|
+
"technical": [
|
|
814
|
+
{ "name": "memory", "type": "skill" },
|
|
815
|
+
{ "name": "tasks", "type": "skill" },
|
|
816
|
+
{ "name": "web_scraping", "type": "tool" }
|
|
817
|
+
],
|
|
818
|
+
"domain": ["grocery_monitoring", "data_analysis"],
|
|
819
|
+
"languages": ["en", "fi"],
|
|
820
|
+
"modules_loaded": ["tier1", "tier1/tasks", "tier1/messages"],
|
|
821
|
+
"limitations": ["session-scoped runtime"]
|
|
822
|
+
}
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
### Tasks — Propose todos
|
|
826
|
+
|
|
827
|
+
```
|
|
828
|
+
PATCH /v1/agents/me/tasks/{id}
|
|
829
|
+
{
|
|
830
|
+
"todos": [
|
|
831
|
+
{ "title": "Check connectivity", "description": "Verify API access", "order": 1, "environment": "aimeat" },
|
|
832
|
+
{ "title": "Write report", "description": "Generate analysis", "order": 2, "environment": "agent" }
|
|
833
|
+
]
|
|
834
|
+
}
|
|
835
|
+
```
|
|
836
|
+
Environment: `aimeat` (runs against AIMEAT API) or `agent` (runs in your local environment).
|
|
837
|
+
|
|
838
|
+
### Tasks — Update a todo
|
|
839
|
+
|
|
840
|
+
```
|
|
841
|
+
PATCH /v1/agents/me/tasks/{id}/todos/{todoId}
|
|
842
|
+
{ "status": "done" }
|
|
843
|
+
```
|
|
844
|
+
Valid statuses: `pending`, `active`, `done`, `failed`, `skipped`
|
|
845
|
+
|
|
846
|
+
### Tasks — Complete
|
|
847
|
+
|
|
848
|
+
```
|
|
849
|
+
POST /v1/agents/me/tasks/{id}/complete
|
|
850
|
+
{ "summary": "All steps executed successfully" }
|
|
851
|
+
```
|
|
852
|
+
|
|
853
|
+
### Telemetry
|
|
854
|
+
|
|
855
|
+
```
|
|
856
|
+
POST /v1/agents/me/telemetry
|
|
857
|
+
{
|
|
858
|
+
"type": "llm_call",
|
|
859
|
+
"tokens_in": 1523,
|
|
860
|
+
"tokens_out": 847,
|
|
861
|
+
"model": "qwen/qwen3.6-plus",
|
|
862
|
+
"duration_ms": 3200
|
|
863
|
+
}
|
|
864
|
+
```
|
|
865
|
+
Types: `llm_call`, `tool_call`, `agent_report`
|
|
866
|
+
|
|
867
|
+
### Messages — Send
|
|
868
|
+
|
|
869
|
+
```
|
|
870
|
+
POST /v1/agents/me/messages
|
|
871
|
+
{
|
|
872
|
+
"thread_id": "optional-thread-id",
|
|
873
|
+
"content": "Hello from my agent",
|
|
874
|
+
"direction": "outbound"
|
|
875
|
+
}
|
|
876
|
+
```
|
|
877
|
+
|
|
878
|
+
### Onboarding — Confirm a step
|
|
879
|
+
|
|
880
|
+
```
|
|
881
|
+
POST /v1/agents/me/onboarding/step/{stepId}
|
|
882
|
+
```
|
|
883
|
+
Step IDs: `authenticate`, `identify_platform`, `install_skill`, `report_capabilities`, `read_directives`, `send_test_message`, `configure_delivery`, `report_telemetry`, `accept_test_task`, `complete_test_task`, `declare_services`
|
|
884
|
+
|
|
885
|
+
Some steps auto-validate when you GET /v1/agents/me/onboarding. The test task auto-starts after you propose todos.
|
|
886
|
+
|
|
887
|
+
### Memory — Write
|
|
888
|
+
|
|
889
|
+
```
|
|
890
|
+
POST /v1/memory
|
|
891
|
+
{
|
|
892
|
+
"key": "agents.my-agent.commands",
|
|
893
|
+
"value": [
|
|
894
|
+
{ "name": "/status", "description": "Show agent status", "category": "general" },
|
|
895
|
+
{ "name": "/inbox", "description": "Check inbox", "category": "tasks" }
|
|
896
|
+
],
|
|
897
|
+
"visibility": "owner"
|
|
898
|
+
}
|
|
899
|
+
```
|
|
900
|
+
The value for commands MUST be a flat array of `{ name, description, category }`. Each name starts with `/`.
|
|
901
|
+
Visibility: `private` (only you), `owner` (you + owner), `public` (everyone)
|
|
902
|
+
|
|
903
|
+
### Inbox — Poll
|
|
904
|
+
|
|
905
|
+
```
|
|
906
|
+
GET /v1/agents/me/inbox
|
|
907
|
+
```
|
|
908
|
+
Returns: `{ "queued_tasks": [...], "active_tasks": [...], "pending_messages": [...] }`
|
|
909
|
+
|
|
804
910
|
## Connecting: MCP (OAuth 2.1)
|
|
805
911
|
|
|
806
912
|
For MCP-capable clients (Claude, Cursor, etc.) that support the Model Context Protocol.
|
package/dist/public/spa.html
CHANGED
|
@@ -66,6 +66,8 @@
|
|
|
66
66
|
<link rel="stylesheet" href="/css/views/capabilities.css">
|
|
67
67
|
<link rel="stylesheet" href="/css/views/agents-detail.css">
|
|
68
68
|
<link rel="stylesheet" href="/css/views/admin.css">
|
|
69
|
+
<link rel="stylesheet" href="/css/views/admin-agent-integration.css">
|
|
70
|
+
<link rel="stylesheet" href="/css/views/public-knowledge-viewer.css">
|
|
69
71
|
<script type="importmap">
|
|
70
72
|
{
|
|
71
73
|
"imports": {
|
|
@@ -143,7 +145,7 @@
|
|
|
143
145
|
"/lib/minidenticons.min.js": "/lib/minidenticons.min.js",
|
|
144
146
|
"/lib/yaml.mjs": "/lib/yaml.mjs",
|
|
145
147
|
"/views/profile/agents-tasks-subtab.js": "/views/profile/agents-tasks-subtab.js",
|
|
146
|
-
"/views/profile/agents-
|
|
148
|
+
"/views/profile/agents-task-builder.js": "/views/profile/agents-task-builder.js",
|
|
147
149
|
"/js/services/agent-tasks.js": "/js/services/agent-tasks.js",
|
|
148
150
|
"/js/services/agent-directives.js": "/js/services/agent-directives.js",
|
|
149
151
|
"/js/services/agent-capabilities.js": "/js/services/agent-capabilities.js",
|
|
@@ -154,7 +156,9 @@
|
|
|
154
156
|
"/views/profile/agents-services-subtab.js": "/views/profile/agents-services-subtab.js",
|
|
155
157
|
"/views/profile/agents-messages-subtab.js": "/views/profile/agents-messages-subtab.js",
|
|
156
158
|
"/js/services/agent-services.js": "/js/services/agent-services.js",
|
|
157
|
-
"/js/services/agent-messages.js": "/js/services/agent-messages.js"
|
|
159
|
+
"/js/services/agent-messages.js": "/js/services/agent-messages.js",
|
|
160
|
+
"/js/services/agent-integration.js": "/js/services/agent-integration.js",
|
|
161
|
+
"/js/services/admin-agent-integration.js": "/js/services/admin-agent-integration.js"
|
|
158
162
|
}
|
|
159
163
|
}
|
|
160
164
|
</script>
|
|
@@ -225,6 +229,7 @@
|
|
|
225
229
|
'/v1/portfolio': () => import('/views/portfolio.js' + B),
|
|
226
230
|
'/v1/admin': () => import('/views/admin.js' + B),
|
|
227
231
|
'/v1/help': () => import('/views/help.js' + B),
|
|
232
|
+
'/v1/publicknowledgeviewer': () => import('/views/public-knowledge-viewer.js' + B),
|
|
228
233
|
};
|
|
229
234
|
|
|
230
235
|
// Match route, handling query params for special views
|
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file agent-integration-tab.js
|
|
3
|
+
* @description Admin dashboard Agent Integration tab. Four sections:
|
|
4
|
+
* Platform Registry, Onboarding Overview (with readiness distribution),
|
|
5
|
+
* Skill Bundle Management, Bundle Templates.
|
|
6
|
+
* @version-history
|
|
7
|
+
* v1.0.0 -- 2026-05-24 -- Initial creation for Governance Phase C
|
|
8
|
+
* v1.1.0 -- 2026-05-24 -- Fix M8 M9 F19 F20 F21 audit findings
|
|
9
|
+
* v1.2.0 -- 2026-05-24 -- Move readiness into onboarding, add bundle templates, add notify button
|
|
10
|
+
*/
|
|
11
|
+
import { h } from 'preact';
|
|
12
|
+
import { useState, useEffect, useCallback } from 'preact/hooks';
|
|
13
|
+
import htm from 'htm';
|
|
14
|
+
const html = htm.bind(h);
|
|
15
|
+
import { t } from '/js/i18n.js';
|
|
16
|
+
import { useViewCSS } from '/components/useViewCSS.js';
|
|
17
|
+
import { num, dt, Empty } from './shared.js';
|
|
18
|
+
import * as api from '/js/services/admin-agent-integration.js';
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
export default function AgentIntegrationTab({ data, session }) {
|
|
22
|
+
useViewCSS('/css/views/admin-agent-integration.css');
|
|
23
|
+
const [platforms, setPlatforms] = useState([]);
|
|
24
|
+
const [onboarding, setOnboarding] = useState(null);
|
|
25
|
+
const [readiness, setReadiness] = useState(null);
|
|
26
|
+
const [bundles, setBundles] = useState(null);
|
|
27
|
+
const [loading, setLoading] = useState(true);
|
|
28
|
+
const [regenerating, setRegenerating] = useState(false);
|
|
29
|
+
|
|
30
|
+
const loadData = useCallback(async () => {
|
|
31
|
+
if (!session) return;
|
|
32
|
+
try {
|
|
33
|
+
const [platRes, onbRes, readRes, bundRes] = await Promise.all([
|
|
34
|
+
api.getPlatforms(session),
|
|
35
|
+
api.getOnboardingOverview(session),
|
|
36
|
+
api.getReadinessDistribution(session),
|
|
37
|
+
api.getSkillBundles(session),
|
|
38
|
+
]);
|
|
39
|
+
setPlatforms(platRes.data?.platforms || []);
|
|
40
|
+
setOnboarding(onbRes.data || null);
|
|
41
|
+
setReadiness(readRes.data || null);
|
|
42
|
+
setBundles(bundRes.data?.bundles || null);
|
|
43
|
+
} catch { /* API unavailable */ }
|
|
44
|
+
setLoading(false);
|
|
45
|
+
}, [session]);
|
|
46
|
+
|
|
47
|
+
useEffect(() => { loadData(); }, [loadData]);
|
|
48
|
+
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
const handler = () => { loadData(); };
|
|
51
|
+
window.addEventListener('aimeat-live-update', handler);
|
|
52
|
+
return () => window.removeEventListener('aimeat-live-update', handler);
|
|
53
|
+
}, [loadData]);
|
|
54
|
+
|
|
55
|
+
if (loading) return html`<div class="adm-card">${t('common.loading')}</div>`;
|
|
56
|
+
|
|
57
|
+
const handleRegenerate = async () => {
|
|
58
|
+
setRegenerating(true);
|
|
59
|
+
try {
|
|
60
|
+
await api.regenerateBundles(session);
|
|
61
|
+
await loadData();
|
|
62
|
+
} catch { /* ignore */ }
|
|
63
|
+
setRegenerating(false);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const totalAgents = platforms.reduce((sum, p) => sum + (p.agent_count || 0), 0);
|
|
67
|
+
|
|
68
|
+
return html`
|
|
69
|
+
<div>
|
|
70
|
+
${renderPlatformRegistry(platforms, totalAgents, session, loadData)}
|
|
71
|
+
${renderOnboardingOverview(onboarding, readiness, session, loadData)}
|
|
72
|
+
${renderSkillBundles(bundles, handleRegenerate, regenerating, session)}
|
|
73
|
+
${renderBundleTemplates()}
|
|
74
|
+
</div>
|
|
75
|
+
`;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* ── M8: Merged Platform column (name + ID as secondary text) ── */
|
|
79
|
+
function renderPlatformRegistry(platforms, totalAgents, session, loadData) {
|
|
80
|
+
const [showForm, setShowForm] = useState(false);
|
|
81
|
+
|
|
82
|
+
return html`
|
|
83
|
+
<div class="adm-agi-section">
|
|
84
|
+
<div class="adm-agi-section-title">${t('admin.agentIntegration.platformRegistry')}</div>
|
|
85
|
+
${platforms.length === 0
|
|
86
|
+
? html`<${Empty} text=${t('admin.agentIntegration.noPlatforms')} />`
|
|
87
|
+
: html`
|
|
88
|
+
<table class="adm-agi-table">
|
|
89
|
+
<thead><tr>
|
|
90
|
+
<th>${t('admin.agentIntegration.platform')}</th>
|
|
91
|
+
<th>${t('admin.agentIntegration.agentCount')}</th>
|
|
92
|
+
<th>${t('admin.agentIntegration.adapter')}</th>
|
|
93
|
+
<th>${t('admin.agentIntegration.detectPattern')}</th>
|
|
94
|
+
</tr></thead>
|
|
95
|
+
<tbody>
|
|
96
|
+
${platforms.map(p => html`
|
|
97
|
+
<tr>
|
|
98
|
+
<td>
|
|
99
|
+
<div>${p.display_name}</div>
|
|
100
|
+
<div class="adm-agi-platform-id">${p.id}</div>
|
|
101
|
+
</td>
|
|
102
|
+
<td>${num(p.agent_count)}</td>
|
|
103
|
+
<td class="adm-agi-mono-sm">${p.bundle_name}</td>
|
|
104
|
+
<td class="adm-agi-mono-sm">${p.detect_pattern || '--'}</td>
|
|
105
|
+
</tr>
|
|
106
|
+
`)}
|
|
107
|
+
</tbody>
|
|
108
|
+
</table>
|
|
109
|
+
<div class="adm-agi-footer">
|
|
110
|
+
${t('admin.agentIntegration.totalAgents')}: ${num(totalAgents)}
|
|
111
|
+
</div>
|
|
112
|
+
`
|
|
113
|
+
}
|
|
114
|
+
${showForm
|
|
115
|
+
? html`<${AddPlatformForm} session=${session} onDone=${() => { setShowForm(false); loadData(); }} onCancel=${() => setShowForm(false)} />`
|
|
116
|
+
: html`<button class="btn-outline adm-agi-add-btn" onClick=${() => setShowForm(true)}>
|
|
117
|
+
${t('admin.agentIntegration.addPlatform')}
|
|
118
|
+
</button>`
|
|
119
|
+
}
|
|
120
|
+
</div>
|
|
121
|
+
`;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/* ── F19: Inline Add Platform form ── */
|
|
125
|
+
function AddPlatformForm({ session, onDone, onCancel }) {
|
|
126
|
+
const [name, setName] = useState('');
|
|
127
|
+
const [id, setId] = useState('');
|
|
128
|
+
const [adapter, setAdapter] = useState('');
|
|
129
|
+
const [pattern, setPattern] = useState('');
|
|
130
|
+
const [submitting, setSubmitting] = useState(false);
|
|
131
|
+
|
|
132
|
+
const handleSubmit = async () => {
|
|
133
|
+
if (!name.trim() || !id.trim()) return;
|
|
134
|
+
setSubmitting(true);
|
|
135
|
+
try {
|
|
136
|
+
await api.registerPlatform(session, {
|
|
137
|
+
id: id.trim(),
|
|
138
|
+
display_name: name.trim(),
|
|
139
|
+
bundle_name: adapter.trim() || undefined,
|
|
140
|
+
detect_pattern: pattern.trim() || undefined,
|
|
141
|
+
});
|
|
142
|
+
onDone();
|
|
143
|
+
} catch { /* ignore */ }
|
|
144
|
+
setSubmitting(false);
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
return html`
|
|
148
|
+
<div class="adm-agi-add-form">
|
|
149
|
+
<div class="adm-agi-add-form-row">
|
|
150
|
+
<label class="adm-agi-add-form-label">${t('admin.agentIntegration.platformName')}</label>
|
|
151
|
+
<input class="adm-agi-add-form-input" value=${name} onInput=${e => setName(e.target.value)} placeholder=${t('admin.agentIntegration.placeholders.name')} />
|
|
152
|
+
</div>
|
|
153
|
+
<div class="adm-agi-add-form-row">
|
|
154
|
+
<label class="adm-agi-add-form-label">${t('admin.agentIntegration.platformId')}</label>
|
|
155
|
+
<input class="adm-agi-add-form-input" value=${id} onInput=${e => setId(e.target.value)} placeholder=${t('admin.agentIntegration.placeholders.id')} />
|
|
156
|
+
</div>
|
|
157
|
+
<div class="adm-agi-add-form-row">
|
|
158
|
+
<label class="adm-agi-add-form-label">${t('admin.agentIntegration.adapterPattern')}</label>
|
|
159
|
+
<input class="adm-agi-add-form-input" value=${adapter} onInput=${e => setAdapter(e.target.value)} placeholder=${t('admin.agentIntegration.placeholders.adapter')} />
|
|
160
|
+
</div>
|
|
161
|
+
<div class="adm-agi-add-form-row">
|
|
162
|
+
<label class="adm-agi-add-form-label">${t('admin.agentIntegration.autoDetectRegex')}</label>
|
|
163
|
+
<input class="adm-agi-add-form-input" value=${pattern} onInput=${e => setPattern(e.target.value)} placeholder=${t('admin.agentIntegration.placeholders.regex')} />
|
|
164
|
+
</div>
|
|
165
|
+
<div class="adm-agi-add-form-actions">
|
|
166
|
+
<button class="btn-primary" onClick=${handleSubmit} disabled=${submitting || !name.trim() || !id.trim()}>
|
|
167
|
+
${submitting ? t('common.loading') : t('common.add')}
|
|
168
|
+
</button>
|
|
169
|
+
<button class="btn-ghost" onClick=${onCancel}>${t('common.cancel')}</button>
|
|
170
|
+
</div>
|
|
171
|
+
</div>
|
|
172
|
+
`;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/* ── M9: Not Started stat card + F20: Stuck section with suggestions + actions ── */
|
|
176
|
+
function renderOnboardingOverview(onboarding, readiness, session, loadData) {
|
|
177
|
+
if (!onboarding) return html`<div class="adm-agi-section"><${Empty} text=${t('common.noData')} /></div>`;
|
|
178
|
+
|
|
179
|
+
const stuck = onboarding.stuck || [];
|
|
180
|
+
const notStarted = onboarding.not_started || 0;
|
|
181
|
+
const readinessTotal = (onboarding.completed || 0) + (onboarding.in_progress || 0) + notStarted;
|
|
182
|
+
|
|
183
|
+
return html`
|
|
184
|
+
<div class="adm-agi-section">
|
|
185
|
+
<div class="adm-agi-section-title">${t('admin.agentIntegration.onboardingOverview')}</div>
|
|
186
|
+
<div class="adm-agi-stats">
|
|
187
|
+
<div class="adm-agi-stat-card">
|
|
188
|
+
<div class="adm-agi-stat-value adm-agi-stat-value--success">${num(onboarding.completed)}</div>
|
|
189
|
+
<div class="adm-agi-stat-label">${t('admin.agentIntegration.completed')}</div>
|
|
190
|
+
</div>
|
|
191
|
+
<div class="adm-agi-stat-card">
|
|
192
|
+
<div class="adm-agi-stat-value adm-agi-stat-value--accent">${num(onboarding.in_progress)}</div>
|
|
193
|
+
<div class="adm-agi-stat-label">${t('admin.agentIntegration.inProgress')}</div>
|
|
194
|
+
</div>
|
|
195
|
+
<div class="adm-agi-stat-card">
|
|
196
|
+
<div class="adm-agi-stat-value">${num(notStarted)}</div>
|
|
197
|
+
<div class="adm-agi-stat-label">${t('admin.agentIntegration.notStarted')}</div>
|
|
198
|
+
</div>
|
|
199
|
+
</div>
|
|
200
|
+
${stuck.length > 0 ? html`
|
|
201
|
+
<div class="adm-agi-stuck-title">${t('admin.agentIntegration.stuckAgents')}</div>
|
|
202
|
+
<div class="adm-agi-stuck">
|
|
203
|
+
${stuck.map(s => html`
|
|
204
|
+
<${StuckAgentRow} agent=${s} session=${session} onAction=${loadData} />
|
|
205
|
+
`)}
|
|
206
|
+
</div>
|
|
207
|
+
` : ''}
|
|
208
|
+
${renderReadinessDistribution(readiness, readinessTotal)}
|
|
209
|
+
</div>
|
|
210
|
+
`;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/* ── F20: Single stuck agent row with suggestion + actions ── */
|
|
214
|
+
function StuckAgentRow({ agent, session, onAction }) {
|
|
215
|
+
const [acting, setActing] = useState(false);
|
|
216
|
+
const suggestion = getSuggestion(agent.current_step);
|
|
217
|
+
|
|
218
|
+
const handleRemind = async () => {
|
|
219
|
+
setActing(true);
|
|
220
|
+
try {
|
|
221
|
+
await api.sendReminder(session, agent.agent_gaii);
|
|
222
|
+
onAction();
|
|
223
|
+
} catch { /* ignore */ }
|
|
224
|
+
setActing(false);
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
const handleSkip = async () => {
|
|
228
|
+
setActing(true);
|
|
229
|
+
try {
|
|
230
|
+
await api.skipOnboardingStep(session, agent.agent_gaii, agent.current_step);
|
|
231
|
+
onAction();
|
|
232
|
+
} catch { /* ignore */ }
|
|
233
|
+
setActing(false);
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
return html`
|
|
237
|
+
<div class="adm-agi-stuck-agent">
|
|
238
|
+
<div class="adm-agi-stuck-info">
|
|
239
|
+
<div>
|
|
240
|
+
<span class="adm-agi-stuck-name">${agent.agent_gaii}</span>
|
|
241
|
+
<div class="adm-agi-stuck-detail">${agent.current_step}</div>
|
|
242
|
+
</div>
|
|
243
|
+
<div class="adm-agi-stuck-detail">
|
|
244
|
+
${t('admin.agentIntegration.stuckSince')}: ${dt(agent.stuck_since)}
|
|
245
|
+
</div>
|
|
246
|
+
<div class="adm-agi-stuck-suggestion">${suggestion}</div>
|
|
247
|
+
</div>
|
|
248
|
+
<div class="adm-agi-stuck-actions">
|
|
249
|
+
<button class="btn-outline adm-agi-stuck-btn" onClick=${handleRemind} disabled=${acting}>
|
|
250
|
+
${t('admin.agentIntegration.sendReminder')}
|
|
251
|
+
</button>
|
|
252
|
+
<button class="btn-ghost adm-agi-stuck-btn" onClick=${handleSkip} disabled=${acting}>
|
|
253
|
+
${t('admin.agentIntegration.skipStep')}
|
|
254
|
+
</button>
|
|
255
|
+
</div>
|
|
256
|
+
</div>
|
|
257
|
+
`;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function getSuggestion(stepId) {
|
|
261
|
+
if (stepId?.includes('webhook') || stepId?.includes('delivery'))
|
|
262
|
+
return t('admin.agentIntegration.suggestion.webhook');
|
|
263
|
+
if (stepId?.includes('platform') || stepId?.includes('detect'))
|
|
264
|
+
return t('admin.agentIntegration.suggestion.platform');
|
|
265
|
+
if (stepId?.includes('skill') || stepId?.includes('bundle'))
|
|
266
|
+
return t('admin.agentIntegration.suggestion.skillBundle');
|
|
267
|
+
return t('admin.agentIntegration.suggestion.default');
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function renderReadinessDistribution(readiness, total) {
|
|
271
|
+
if (!readiness) return '';
|
|
272
|
+
const dist = readiness.distribution || {};
|
|
273
|
+
const levels = ['expert', 'full', 'standard', 'basic'];
|
|
274
|
+
|
|
275
|
+
return html`
|
|
276
|
+
<div class="adm-agi-subsection">
|
|
277
|
+
<div class="adm-agi-section-title">${t('admin.agentIntegration.readinessDistribution')}</div>
|
|
278
|
+
${total === 0
|
|
279
|
+
? html`<div class="adm-agi-empty-text">${t('common.noData')}</div>`
|
|
280
|
+
: html`
|
|
281
|
+
${levels.map(level => {
|
|
282
|
+
const count = dist[level] || 0;
|
|
283
|
+
const pct = total > 0 ? (count / total * 100) : 0;
|
|
284
|
+
return html`
|
|
285
|
+
<div class="adm-agi-readiness-bar">
|
|
286
|
+
<div class="adm-agi-readiness-level">${t(`agentOnboarding.readiness.${level}`)}</div>
|
|
287
|
+
<div class="adm-agi-readiness-track">
|
|
288
|
+
<div class="adm-agi-readiness-fill" style="width:${pct}%" data-level="${level}"></div>
|
|
289
|
+
</div>
|
|
290
|
+
<div class="adm-agi-readiness-count">${count}</div>
|
|
291
|
+
</div>
|
|
292
|
+
`;
|
|
293
|
+
})}
|
|
294
|
+
<div class="adm-agi-footer">
|
|
295
|
+
${t('admin.agentIntegration.totalAgents')}: ${num(total)}
|
|
296
|
+
</div>
|
|
297
|
+
`
|
|
298
|
+
}
|
|
299
|
+
</div>
|
|
300
|
+
`;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/* ── F21: Added "Current version" column to skill bundle table ── */
|
|
304
|
+
function renderSkillBundles(bundles, onRegenerate, regenerating, session) {
|
|
305
|
+
if (!bundles) return '';
|
|
306
|
+
const entries = Object.entries(bundles);
|
|
307
|
+
|
|
308
|
+
const handleNotify = async (platform) => {
|
|
309
|
+
try {
|
|
310
|
+
await api.notifyOutdatedAgents(session, platform);
|
|
311
|
+
window.dispatchEvent(new CustomEvent('aimeat-toast', { detail: { message: t('admin.agentIntegration.notifySuccess') } }));
|
|
312
|
+
} catch { /* ignore */ }
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
return html`
|
|
316
|
+
<div class="adm-agi-section">
|
|
317
|
+
<div class="adm-agi-section-title">${t('admin.agentIntegration.skillBundles')}</div>
|
|
318
|
+
${entries.length === 0
|
|
319
|
+
? html`<div class="adm-agi-empty-text">${t('common.noData')}</div>`
|
|
320
|
+
: html`
|
|
321
|
+
<table class="adm-agi-table">
|
|
322
|
+
<thead><tr>
|
|
323
|
+
<th>${t('admin.agentIntegration.platform')}</th>
|
|
324
|
+
<th>${t('admin.agentIntegration.agentCount')}</th>
|
|
325
|
+
<th>${t('admin.agentIntegration.currentVersion')}</th>
|
|
326
|
+
<th>${t('admin.agentIntegration.outdated')}</th>
|
|
327
|
+
<th></th>
|
|
328
|
+
</tr></thead>
|
|
329
|
+
<tbody>
|
|
330
|
+
${entries.map(([platform, info]) => html`
|
|
331
|
+
<tr>
|
|
332
|
+
<td>${platform}</td>
|
|
333
|
+
<td>${num(info.agents)}</td>
|
|
334
|
+
<td class="adm-agi-mono-sm">${info.version || info.currentVersion || '--'}</td>
|
|
335
|
+
<td>${info.outdated > 0
|
|
336
|
+
? html`<span class="adm-agi-outdated">${num(info.outdated)}</span>`
|
|
337
|
+
: html`<span class="adm-agi-zero">0</span>`
|
|
338
|
+
}</td>
|
|
339
|
+
<td>${info.outdated > 0 ? html`
|
|
340
|
+
<button class="btn-outline adm-agi-notify-btn" onClick=${() => handleNotify(platform)}>
|
|
341
|
+
${t('admin.agentIntegration.notifyOutdated')}
|
|
342
|
+
</button>
|
|
343
|
+
` : ''}</td>
|
|
344
|
+
</tr>
|
|
345
|
+
`)}
|
|
346
|
+
</tbody>
|
|
347
|
+
</table>
|
|
348
|
+
`
|
|
349
|
+
}
|
|
350
|
+
<button class="btn-outline adm-agi-regen-btn" onClick=${onRegenerate} disabled=${regenerating}>
|
|
351
|
+
${regenerating ? t('common.loading') : t('admin.agentIntegration.regenerateAll')}
|
|
352
|
+
</button>
|
|
353
|
+
</div>
|
|
354
|
+
`;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/* ── Bundle Templates (Phase C stub) ── */
|
|
358
|
+
function renderBundleTemplates() {
|
|
359
|
+
const handleComingSoon = () => {
|
|
360
|
+
window.dispatchEvent(new CustomEvent('aimeat-toast', { detail: { message: t('admin.agentIntegration.comingSoon') } }));
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
return html`
|
|
364
|
+
<div class="adm-agi-section">
|
|
365
|
+
<div class="adm-agi-section-title">${t('admin.agentIntegration.bundleTemplates')}</div>
|
|
366
|
+
<div class="adm-agi-stats">
|
|
367
|
+
<div class="adm-agi-stat-card">
|
|
368
|
+
<div class="adm-agi-stat-value">0</div>
|
|
369
|
+
<div class="adm-agi-stat-label">${t('admin.agentIntegration.customReferences')}</div>
|
|
370
|
+
</div>
|
|
371
|
+
<div class="adm-agi-stat-card">
|
|
372
|
+
<div class="adm-agi-stat-value">0</div>
|
|
373
|
+
<div class="adm-agi-stat-label">${t('admin.agentIntegration.customScripts')}</div>
|
|
374
|
+
</div>
|
|
375
|
+
<div class="adm-agi-stat-card">
|
|
376
|
+
<div class="adm-agi-stat-value adm-agi-mono-sm">--</div>
|
|
377
|
+
<div class="adm-agi-stat-label">${t('admin.agentIntegration.lastGenerated')}</div>
|
|
378
|
+
</div>
|
|
379
|
+
</div>
|
|
380
|
+
<div class="adm-agi-btn-row">
|
|
381
|
+
<button class="btn-outline" onClick=${handleComingSoon}>
|
|
382
|
+
${t('admin.agentIntegration.customizeBundle')}
|
|
383
|
+
</button>
|
|
384
|
+
<button class="btn-outline" onClick=${handleComingSoon}>
|
|
385
|
+
${t('admin.agentIntegration.previewBundle')}
|
|
386
|
+
</button>
|
|
387
|
+
</div>
|
|
388
|
+
</div>
|
|
389
|
+
`;
|
|
390
|
+
}
|
|
@@ -38,10 +38,10 @@ export default function FederationTab({ data, reload }) {
|
|
|
38
38
|
|
|
39
39
|
useEffect(() => {
|
|
40
40
|
getConfig().then(res => {
|
|
41
|
-
if (res.ok && res.data?.
|
|
42
|
-
const
|
|
43
|
-
setAuthPolicy(
|
|
44
|
-
const scopes =
|
|
41
|
+
if (res.ok && res.data?.schema) {
|
|
42
|
+
const s = res.data.schema;
|
|
43
|
+
setAuthPolicy(s['federation.auth_policy']?.value ?? 'disabled');
|
|
44
|
+
const scopes = s['federation.default_scopes']?.value ?? 'memory:read,catalogue:read';
|
|
45
45
|
setDefaultScopes(typeof scopes === 'string' ? scopes.split(',').filter(Boolean) : (scopes || []));
|
|
46
46
|
}
|
|
47
47
|
setAuthPolicyLoading(false);
|
|
@@ -385,7 +385,7 @@ export default function FederationTab({ data, reload }) {
|
|
|
385
385
|
${(p.status === 'active' || p.status === 'degraded') && html`
|
|
386
386
|
<button class="adm-btn-sm" onClick=${() => doRemove(p.node_id)}>${t('dashboard.fedDepeer')}</button>
|
|
387
387
|
`}
|
|
388
|
-
${p.status === 'active' && html`
|
|
388
|
+
${(p.status === 'active' || p.status === 'degraded' || p.status === 'offline' || p.status === 'depeering') && html`
|
|
389
389
|
<button class="adm-btn-sm adm-text-error" onClick=${() => doEmergencyRemove(p.node_id)}>\u26A0 ${t('dashboard.fedEmergencyDepeer')}</button>
|
|
390
390
|
`}
|
|
391
391
|
</td>
|