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
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file tab-messages.js
|
|
3
|
+
* @description Messages tab with command palette, "/" autocomplete, and chat area.
|
|
4
|
+
* Wraps the existing messages subtab and adds command discovery.
|
|
5
|
+
* @version-history
|
|
6
|
+
* v1.2.0 -- 2026-05-24 -- Add command-reply visual pairing for slash commands
|
|
7
|
+
* v1.1.0 -- 2026-05-24 -- M7: visual distinction for command messages (slash prefix)
|
|
8
|
+
* v1.0.0 -- 2026-05-24 -- Initial creation for Agent Detail Tab-View
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { h } from 'preact';
|
|
12
|
+
import { useState, useEffect, useRef, useMemo } from 'preact/hooks';
|
|
13
|
+
import htm from 'htm';
|
|
14
|
+
import { t } from '/js/i18n.js';
|
|
15
|
+
import { timeAgo } from '/js/utils.js';
|
|
16
|
+
import { sendMessage, listMessages, listThreads } from '/js/services/agent-messages.js';
|
|
17
|
+
import { getAgentCommands } from '/js/services/agent-integration.js';
|
|
18
|
+
|
|
19
|
+
const html = htm.bind(h);
|
|
20
|
+
|
|
21
|
+
function CommandPalette({ commands, onSend }) {
|
|
22
|
+
const [expanded, setExpanded] = useState(false);
|
|
23
|
+
|
|
24
|
+
if (!commands || commands.length === 0) {
|
|
25
|
+
return html`
|
|
26
|
+
<div class="pf-agd-commands">
|
|
27
|
+
<div class="pf-agd-commands-header" onClick=${() => setExpanded(!expanded)}>
|
|
28
|
+
<span>${t('profile.agents.detail.messages.commands.title')} (0)</span>
|
|
29
|
+
<span>${expanded ? '▼' : '▶'}</span>
|
|
30
|
+
</div>
|
|
31
|
+
${expanded && html`
|
|
32
|
+
<div class="pf-agd-commands-body">
|
|
33
|
+
<div class="pf-agd-empty">${t('profile.agents.detail.messages.commands.noCommands')}</div>
|
|
34
|
+
<div class="pf-agd-empty-hint">${t('profile.agents.detail.messages.commands.noCommandsHint')}</div>
|
|
35
|
+
</div>
|
|
36
|
+
`}
|
|
37
|
+
</div>
|
|
38
|
+
`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const categories = useMemo(() => {
|
|
42
|
+
const cats = {};
|
|
43
|
+
for (const cmd of commands) {
|
|
44
|
+
const cat = cmd.category || t('profile.agents.detail.messages.commands.defaultCategory');
|
|
45
|
+
if (!cats[cat]) cats[cat] = [];
|
|
46
|
+
cats[cat].push(cmd);
|
|
47
|
+
}
|
|
48
|
+
return cats;
|
|
49
|
+
}, [commands]);
|
|
50
|
+
|
|
51
|
+
return html`
|
|
52
|
+
<div class="pf-agd-commands">
|
|
53
|
+
<div class="pf-agd-commands-header" onClick=${() => setExpanded(!expanded)}>
|
|
54
|
+
<span>${t('profile.agents.detail.messages.commands.title')} (${commands.length} ${t('profile.agents.detail.messages.commands.available')})</span>
|
|
55
|
+
<span>${expanded ? '▼' : '▶'}</span>
|
|
56
|
+
</div>
|
|
57
|
+
${expanded && html`
|
|
58
|
+
<div class="pf-agd-commands-body">
|
|
59
|
+
${Object.entries(categories).map(([cat, cmds]) => html`
|
|
60
|
+
<div key=${cat}>
|
|
61
|
+
<div class="pf-agd-commands-category">${cat}</div>
|
|
62
|
+
${cmds.map(cmd => html`
|
|
63
|
+
<div key=${cmd.name} class="pf-agd-command-row">
|
|
64
|
+
<span class="pf-agd-command-name">${cmd.name}</span>
|
|
65
|
+
<span class="pf-agd-command-desc">${cmd.description || ''}</span>
|
|
66
|
+
<button class="btn-outline btn-sm" onClick=${() => onSend(cmd.name)}>
|
|
67
|
+
${t('profile.agents.detail.messages.commands.send')}
|
|
68
|
+
</button>
|
|
69
|
+
</div>
|
|
70
|
+
`)}
|
|
71
|
+
</div>
|
|
72
|
+
`)}
|
|
73
|
+
</div>
|
|
74
|
+
`}
|
|
75
|
+
</div>
|
|
76
|
+
`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export default function TabMessages({ agent, agentName, session, showToast }) {
|
|
80
|
+
const [commands, setCommands] = useState([]);
|
|
81
|
+
const [messages, setMessages] = useState([]);
|
|
82
|
+
const [threads, setThreads] = useState([]);
|
|
83
|
+
const [activeThread, setActiveThread] = useState(null);
|
|
84
|
+
const [loading, setLoading] = useState(true);
|
|
85
|
+
const [sending, setSending] = useState(false);
|
|
86
|
+
const [draft, setDraft] = useState('');
|
|
87
|
+
const [showAutocomplete, setShowAutocomplete] = useState(false);
|
|
88
|
+
const historyRef = useRef(null);
|
|
89
|
+
|
|
90
|
+
async function loadCommands() {
|
|
91
|
+
try {
|
|
92
|
+
const resp = await getAgentCommands(agentName, agent.gaii);
|
|
93
|
+
const data = resp?.data?.value;
|
|
94
|
+
if (Array.isArray(data)) setCommands(data);
|
|
95
|
+
else if (typeof data === 'string') {
|
|
96
|
+
try { setCommands(JSON.parse(data)); } catch { setCommands([]); }
|
|
97
|
+
} else {
|
|
98
|
+
setCommands([]);
|
|
99
|
+
}
|
|
100
|
+
} catch { setCommands([]); }
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function loadMessages() {
|
|
104
|
+
try {
|
|
105
|
+
const opts = {};
|
|
106
|
+
if (activeThread) opts.threadId = activeThread;
|
|
107
|
+
const res = await listMessages(agentName, opts);
|
|
108
|
+
setMessages(res?.data?.messages || []);
|
|
109
|
+
} catch { setMessages([]); }
|
|
110
|
+
setLoading(false);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async function loadThreads() {
|
|
114
|
+
try {
|
|
115
|
+
const res = await listThreads(agentName);
|
|
116
|
+
setThreads(res?.data?.threads || []);
|
|
117
|
+
} catch { setThreads([]); }
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
useEffect(() => {
|
|
121
|
+
loadCommands();
|
|
122
|
+
loadThreads();
|
|
123
|
+
loadMessages();
|
|
124
|
+
}, [agentName]);
|
|
125
|
+
|
|
126
|
+
useEffect(() => { loadMessages(); }, [activeThread]);
|
|
127
|
+
|
|
128
|
+
useEffect(() => {
|
|
129
|
+
const handler = () => { loadMessages(); loadThreads(); loadCommands(); };
|
|
130
|
+
window.addEventListener('aimeat-live-update', handler);
|
|
131
|
+
const poller = setInterval(handler, 10000);
|
|
132
|
+
return () => { window.removeEventListener('aimeat-live-update', handler); clearInterval(poller); };
|
|
133
|
+
}, [agentName, activeThread]);
|
|
134
|
+
|
|
135
|
+
useEffect(() => {
|
|
136
|
+
if (historyRef.current) {
|
|
137
|
+
historyRef.current.scrollTop = historyRef.current.scrollHeight;
|
|
138
|
+
}
|
|
139
|
+
}, [messages]);
|
|
140
|
+
|
|
141
|
+
async function handleSend(text) {
|
|
142
|
+
const msg = text || draft.trim();
|
|
143
|
+
if (!msg) return;
|
|
144
|
+
setSending(true);
|
|
145
|
+
try {
|
|
146
|
+
await sendMessage(agentName, msg, activeThread);
|
|
147
|
+
setDraft('');
|
|
148
|
+
setShowAutocomplete(false);
|
|
149
|
+
await loadMessages();
|
|
150
|
+
} catch (err) {
|
|
151
|
+
showToast(err.message || t('profile.agents.detail.messages.sendError'), true);
|
|
152
|
+
}
|
|
153
|
+
setSending(false);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function handleKeyDown(e) {
|
|
157
|
+
if (e.key === 'Enter' && !e.shiftKey) {
|
|
158
|
+
e.preventDefault();
|
|
159
|
+
handleSend();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function handleInput(e) {
|
|
164
|
+
const val = e.target.value;
|
|
165
|
+
setDraft(val);
|
|
166
|
+
setShowAutocomplete(val.startsWith('/') && commands.length > 0);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const filteredCommands = useMemo(() => {
|
|
170
|
+
if (!draft.startsWith('/')) return [];
|
|
171
|
+
const search = draft.toLowerCase();
|
|
172
|
+
return commands.filter(c => c.name.toLowerCase().startsWith(search));
|
|
173
|
+
}, [draft, commands]);
|
|
174
|
+
|
|
175
|
+
function selectCommand(cmdName) {
|
|
176
|
+
setDraft(cmdName);
|
|
177
|
+
setShowAutocomplete(false);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function renderMessage(msg, isCommand, isReply) {
|
|
181
|
+
return html`
|
|
182
|
+
<div key=${msg.id || msg.createdAt}>
|
|
183
|
+
<div class="pf-agd-msg-bubble ${msg.direction === 'inbound' ? 'pf-agd-msg-inbound' : 'pf-agd-msg-outbound'} ${isCommand ? 'pf-agd-msg-command' : ''} ${isReply ? 'pf-agd-msg-reply' : ''}">
|
|
184
|
+
${isCommand && html`<span class="pf-agd-command-badge">${t('profile.agents.detail.messages.command')}</span>`}
|
|
185
|
+
${msg.content}
|
|
186
|
+
</div>
|
|
187
|
+
<div class="pf-agd-msg-meta ${msg.direction === 'inbound' ? 'pf-agd-msg-meta-right' : ''}">
|
|
188
|
+
${msg.createdAt ? html`<span class="pf-agd-msg-time">${new Date(msg.createdAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}</span> ${timeAgo(msg.createdAt)}` : ''}
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
`;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (loading && messages.length === 0) {
|
|
195
|
+
return html`<div class="pf-agd-empty">${t('profile.loading')}</div>`;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return html`
|
|
199
|
+
<div>
|
|
200
|
+
<${CommandPalette} commands=${commands} onSend=${(cmd) => handleSend(cmd)} />
|
|
201
|
+
|
|
202
|
+
${threads.length > 0 && html`
|
|
203
|
+
<div class="pf-agd-msg-threads">
|
|
204
|
+
<button class="pf-agd-msg-thread-btn ${!activeThread ? 'pf-agd-msg-thread-btn-active' : ''}"
|
|
205
|
+
onClick=${() => setActiveThread(null)}>
|
|
206
|
+
${t('profile.agents.messages.threads')}
|
|
207
|
+
</button>
|
|
208
|
+
${threads.map(thread => html`
|
|
209
|
+
<button key=${thread.id}
|
|
210
|
+
class="pf-agd-msg-thread-btn ${activeThread === thread.id ? 'pf-agd-msg-thread-btn-active' : ''}"
|
|
211
|
+
onClick=${() => setActiveThread(thread.id)}>
|
|
212
|
+
${thread.title || thread.id?.slice(0, 8) || '...'}
|
|
213
|
+
</button>
|
|
214
|
+
`)}
|
|
215
|
+
</div>
|
|
216
|
+
`}
|
|
217
|
+
|
|
218
|
+
${messages.length === 0 && !loading && html`
|
|
219
|
+
<div class="pf-agd-empty">${t('profile.agents.detail.empty.messages')}</div>
|
|
220
|
+
`}
|
|
221
|
+
|
|
222
|
+
${messages.length > 0 && html`
|
|
223
|
+
<div class="pf-agd-msg-history" ref=${historyRef}>
|
|
224
|
+
${(() => {
|
|
225
|
+
const sorted = [...messages].sort((a, b) => new Date(a.createdAt || 0) - new Date(b.createdAt || 0));
|
|
226
|
+
const rendered = [];
|
|
227
|
+
for (let i = 0; i < sorted.length; i++) {
|
|
228
|
+
const msg = sorted[i];
|
|
229
|
+
const isCommand = msg.content?.startsWith('/') && msg.direction === 'inbound';
|
|
230
|
+
const nextMsg = sorted[i + 1];
|
|
231
|
+
const hasReply = isCommand && nextMsg && nextMsg.direction === 'outbound';
|
|
232
|
+
|
|
233
|
+
if (hasReply) {
|
|
234
|
+
rendered.push(html`
|
|
235
|
+
<div class="pf-agd-msg-pair" key=${msg.id || msg.createdAt}>
|
|
236
|
+
${renderMessage(msg, true, false)}
|
|
237
|
+
<div class="pf-agd-msg-reply-indicator">↳</div>
|
|
238
|
+
${renderMessage(nextMsg, false, true)}
|
|
239
|
+
</div>
|
|
240
|
+
`);
|
|
241
|
+
i++;
|
|
242
|
+
} else {
|
|
243
|
+
rendered.push(renderMessage(msg, isCommand, false));
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return rendered;
|
|
247
|
+
})()}
|
|
248
|
+
</div>
|
|
249
|
+
`}
|
|
250
|
+
|
|
251
|
+
<div class="pf-agd-msg-input">
|
|
252
|
+
<div class="pf-agd-input-wrap">
|
|
253
|
+
${showAutocomplete && filteredCommands.length > 0 && html`
|
|
254
|
+
<div class="pf-agd-autocomplete">
|
|
255
|
+
${filteredCommands.map(cmd => html`
|
|
256
|
+
<div key=${cmd.name} class="pf-agd-autocomplete-item" onClick=${() => selectCommand(cmd.name)}>
|
|
257
|
+
<span class="pf-agd-command-name">${cmd.name}</span>
|
|
258
|
+
<span class="pf-agd-command-desc">${cmd.description || ''}</span>
|
|
259
|
+
</div>
|
|
260
|
+
`)}
|
|
261
|
+
</div>
|
|
262
|
+
`}
|
|
263
|
+
<textarea
|
|
264
|
+
value=${draft}
|
|
265
|
+
onInput=${handleInput}
|
|
266
|
+
onKeyDown=${handleKeyDown}
|
|
267
|
+
placeholder=${t('profile.agents.detail.messages.placeholder')}
|
|
268
|
+
rows="1"
|
|
269
|
+
/>
|
|
270
|
+
</div>
|
|
271
|
+
<button class="btn-primary btn-sm" onClick=${() => handleSend()} disabled=${sending || !draft.trim()}>
|
|
272
|
+
${t('profile.agents.messages.send')}
|
|
273
|
+
</button>
|
|
274
|
+
</div>
|
|
275
|
+
<div class="pf-agd-msg-meta">${t('profile.agents.detail.messages.hint')}</div>
|
|
276
|
+
</div>
|
|
277
|
+
`;
|
|
278
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file tab-services.js
|
|
3
|
+
* @description Services tab -- declared services list with active/inactive status.
|
|
4
|
+
* Wraps the existing services subtab component.
|
|
5
|
+
* @version-history
|
|
6
|
+
* v1.0.0 -- 2026-05-24 -- Initial creation for Agent Detail Tab-View
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { h } from 'preact';
|
|
10
|
+
import htm from 'htm';
|
|
11
|
+
import AgentServicesSubtab from '../agents-services-subtab.js';
|
|
12
|
+
|
|
13
|
+
const html = htm.bind(h);
|
|
14
|
+
|
|
15
|
+
export default function TabServices({ agentName, session, showToast }) {
|
|
16
|
+
return html`<${AgentServicesSubtab} agentName=${agentName} session=${session} showToast=${showToast} />`;
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file tab-tasks.js
|
|
3
|
+
* @description Tasks tab wrapper for agent detail tab-view.
|
|
4
|
+
* Delegates to the existing AgentTasksSubtab component.
|
|
5
|
+
* @version-history
|
|
6
|
+
* v1.0.0 -- 2026-05-24 -- Initial creation for Agent Detail Tab-View
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { h } from 'preact';
|
|
10
|
+
import htm from 'htm';
|
|
11
|
+
import AgentTasksSubtab from '../agents-tasks-subtab.js';
|
|
12
|
+
|
|
13
|
+
const html = htm.bind(h);
|
|
14
|
+
|
|
15
|
+
export default function TabTasks({ agentName, session, showToast }) {
|
|
16
|
+
return html`<${AgentTasksSubtab} agentName=${agentName} session=${session} showToast=${showToast} />`;
|
|
17
|
+
}
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
* - ProposedTask -- task proposal from agent with create/adjust buttons
|
|
10
10
|
* - ThreadList -- horizontal thread selector
|
|
11
11
|
* @version-history
|
|
12
|
+
* v1.2.0 -- 2026-05-22 -- Fix: use camelCase field names from API (createdAt, metadata.tokensUsed)
|
|
13
|
+
* v1.1.0 -- 2026-05-22 -- Show timestamp on messages, sort oldest-first (chat-style)
|
|
12
14
|
* v1.0.0 -- 2026-05-22 -- Initial creation for Agent Dashboard Phase 3
|
|
13
15
|
*/
|
|
14
16
|
import { h } from 'preact';
|
|
@@ -27,13 +29,13 @@ function ProposedTask({ task, agentName, showToast }) {
|
|
|
27
29
|
setCreating(true);
|
|
28
30
|
try {
|
|
29
31
|
await createTask(agentName, {
|
|
30
|
-
title: task.title || task.summary || '
|
|
32
|
+
title: task.title || task.summary || t('profile.agents.messages.proposedTaskDefault'),
|
|
31
33
|
description: task.description || '',
|
|
32
34
|
status: 'queued',
|
|
33
35
|
});
|
|
34
36
|
showToast(t('profile.agents.tasks.createTask'));
|
|
35
37
|
} catch (err) {
|
|
36
|
-
showToast(err.message || '
|
|
38
|
+
showToast(err.message || t('profile.agents.messages.createTaskError'), true);
|
|
37
39
|
}
|
|
38
40
|
setCreating(false);
|
|
39
41
|
}
|
|
@@ -66,8 +68,8 @@ function MessageBubble({ msg, agentName, showToast }) {
|
|
|
66
68
|
${msg.content}
|
|
67
69
|
</div>
|
|
68
70
|
<div class="agd-msg-meta ${isInbound ? 'agd-msg-meta-right' : ''}">
|
|
69
|
-
${msg.
|
|
70
|
-
${msg.
|
|
71
|
+
${msg.createdAt ? html`<span class="agd-msg-time">${new Date(msg.createdAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}</span> ${timeAgo(msg.createdAt)}` : ''}
|
|
72
|
+
${msg.metadata?.tokensUsed ? html` · ${msg.metadata.tokensUsed} ${t('profile.agents.messages.tokensUsed')}` : ''}
|
|
71
73
|
</div>
|
|
72
74
|
${proposedTask && html`
|
|
73
75
|
<${ProposedTask} task=${proposedTask} agentName=${agentName} showToast=${showToast} />
|
|
@@ -157,7 +159,7 @@ export default function AgentMessagesSubtab({ agentName, session, showToast }) {
|
|
|
157
159
|
setDraft('');
|
|
158
160
|
await loadMessages();
|
|
159
161
|
} catch (err) {
|
|
160
|
-
showToast(err.message || '
|
|
162
|
+
showToast(err.message || t('profile.agents.messages.sendError'), true);
|
|
161
163
|
}
|
|
162
164
|
setSending(false);
|
|
163
165
|
}
|
|
@@ -185,9 +187,9 @@ export default function AgentMessagesSubtab({ agentName, session, showToast }) {
|
|
|
185
187
|
<span class="${lastSeen ? 'badge badge-success' : 'badge badge-muted'}">${lastSeen ? t('profile.agents.messages.online') : t('profile.agents.messages.offline')}</span>
|
|
186
188
|
</div>
|
|
187
189
|
<div class="agd-msg-status-counts">
|
|
188
|
-
<span class="badge badge-muted"
|
|
189
|
-
<span class="badge badge-muted"
|
|
190
|
-
${errorCount > 0 && html`<span class="badge badge-danger"
|
|
190
|
+
<span class="badge badge-muted">${t('profile.agents.messages.inboxLabel')}: ${pendingCount}</span>
|
|
191
|
+
<span class="badge badge-muted">${t('profile.agents.messages.deliveredLabel')}: ${deliveredCount}</span>
|
|
192
|
+
${errorCount > 0 && html`<span class="badge badge-danger">${t('profile.agents.messages.errorsLabel')}: ${errorCount}</span>`}
|
|
191
193
|
</div>
|
|
192
194
|
</div>
|
|
193
195
|
|
|
@@ -199,8 +201,8 @@ export default function AgentMessagesSubtab({ agentName, session, showToast }) {
|
|
|
199
201
|
|
|
200
202
|
${messages.length > 0 && html`
|
|
201
203
|
<div class="agd-msg-history" ref=${historyRef}>
|
|
202
|
-
${messages.map(msg => html`
|
|
203
|
-
<${MessageBubble} key=${msg.id || msg.
|
|
204
|
+
${[...messages].sort((a, b) => new Date(a.createdAt || 0) - new Date(b.createdAt || 0)).map(msg => html`
|
|
205
|
+
<${MessageBubble} key=${msg.id || msg.createdAt} msg=${msg} agentName=${agentName} showToast=${showToast} />
|
|
204
206
|
`)}
|
|
205
207
|
</div>
|
|
206
208
|
`}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* - AgentServicesSubtab (default export) -- main component
|
|
8
8
|
* - ServiceCard -- individual service display card
|
|
9
9
|
* @version-history
|
|
10
|
+
* v1.1.0 -- 2026-05-24 -- Fix locale keys; add status dots and active/inactive labels
|
|
10
11
|
* v1.0.0 -- 2026-05-22 -- Initial creation for Agent Dashboard Phase 3
|
|
11
12
|
*/
|
|
12
13
|
import { h } from 'preact';
|
|
@@ -17,24 +18,29 @@ import { t } from '/js/i18n.js';
|
|
|
17
18
|
import { getAgentServices } from '/js/services/agent-services.js';
|
|
18
19
|
|
|
19
20
|
function ServiceCard({ service, onUnpublish }) {
|
|
20
|
-
const name = service.display_name || service.name || service.action_id || '
|
|
21
|
+
const name = service.display_name || service.name || service.action_id || t('profile.agents.services.unnamed');
|
|
21
22
|
const desc = service.description || '';
|
|
22
|
-
const cost = service.cost != null ? `${service.cost} morsels` : '
|
|
23
|
-
const visibility = service.visibility || 'public';
|
|
23
|
+
const cost = service.cost != null ? `${service.cost} ${t('profile.agents.services.morsels')}` : t('profile.agents.services.free');
|
|
24
|
+
const visibility = t('profile.agents.services.visibility.' + (service.visibility || 'public'));
|
|
25
|
+
const isActive = service.active !== false && service.status !== 'inactive';
|
|
24
26
|
const calls = service.invocation_count || service.call_count || 0;
|
|
25
27
|
const successRate = service.success_rate != null ? `${Math.round(service.success_rate)}%` : null;
|
|
26
28
|
const avgResponse = service.avg_response_ms != null ? `${Math.round(service.avg_response_ms)}ms` : null;
|
|
27
29
|
|
|
28
30
|
return html`
|
|
29
31
|
<div class="agd-service-card">
|
|
30
|
-
<div class="agd-service-name"
|
|
32
|
+
<div class="agd-service-name">
|
|
33
|
+
<span class="pf-agd-status-dot ${isActive ? 'pf-agd-status-dot--active' : 'pf-agd-status-dot--inactive'}"></span>
|
|
34
|
+
${name}
|
|
35
|
+
</div>
|
|
31
36
|
${desc && html`<div class="agd-service-desc">${desc}</div>`}
|
|
32
37
|
<div class="agd-service-meta">
|
|
33
38
|
<span>${cost}</span>
|
|
34
39
|
<span>${visibility}</span>
|
|
40
|
+
<span class="pf-agd-badge ${isActive ? 'pf-agd-badge--active' : 'pf-agd-badge--inactive'}">${isActive ? t('profile.agents.detail.services.active') : t('profile.agents.detail.services.inactive')}</span>
|
|
35
41
|
<span>${calls} ${t('profile.agents.services.calls')}</span>
|
|
36
42
|
${successRate && html`<span>${successRate} ${t('profile.agents.activity.successRate')}</span>`}
|
|
37
|
-
${avgResponse && html`<span>${avgResponse} avg</span>`}
|
|
43
|
+
${avgResponse && html`<span>${avgResponse} ${t('profile.agents.services.avg')}</span>`}
|
|
38
44
|
</div>
|
|
39
45
|
<div class="agd-service-actions">
|
|
40
46
|
<button class="btn-ghost btn-sm" onClick=${() => onUnpublish(service)}>
|
|
@@ -55,7 +61,7 @@ export default function AgentServicesSubtab({ agentName, session, showToast }) {
|
|
|
55
61
|
const res = await getAgentServices(agentName);
|
|
56
62
|
setServices(res.actions || []);
|
|
57
63
|
} catch (err) {
|
|
58
|
-
showToast(err.message || '
|
|
64
|
+
showToast(err.message || t('profile.agents.services.loadError'), true);
|
|
59
65
|
}
|
|
60
66
|
setLoading(false);
|
|
61
67
|
}
|
|
@@ -68,14 +74,14 @@ export default function AgentServicesSubtab({ agentName, session, showToast }) {
|
|
|
68
74
|
headers: { 'Authorization': `Bearer ${session?.token}` },
|
|
69
75
|
});
|
|
70
76
|
if (resp.ok) {
|
|
71
|
-
showToast(t('profile.agents.services.
|
|
77
|
+
showToast(t('profile.agents.services.unpublished'));
|
|
72
78
|
loadServices();
|
|
73
79
|
} else {
|
|
74
80
|
const body = await resp.json().catch(() => ({}));
|
|
75
|
-
showToast(body.error?.message || '
|
|
81
|
+
showToast(body.error?.message || t('profile.agents.services.unpublishError'), true);
|
|
76
82
|
}
|
|
77
83
|
} catch (err) {
|
|
78
|
-
showToast(err.message || '
|
|
84
|
+
showToast(err.message || t('profile.agents.services.unpublishError'), true);
|
|
79
85
|
}
|
|
80
86
|
}
|
|
81
87
|
|
|
@@ -94,11 +100,11 @@ export default function AgentServicesSubtab({ agentName, session, showToast }) {
|
|
|
94
100
|
return html`
|
|
95
101
|
<div>
|
|
96
102
|
<div class="agd-services-info">
|
|
97
|
-
${t('profile.agents.services.info')}
|
|
103
|
+
${t('profile.agents.detail.services.info')}
|
|
98
104
|
</div>
|
|
99
105
|
|
|
100
106
|
${services.length === 0 && html`
|
|
101
|
-
<div class="agd-empty">${t('profile.agents.
|
|
107
|
+
<div class="agd-empty">${t('profile.agents.detail.empty.services')}</div>
|
|
102
108
|
`}
|
|
103
109
|
|
|
104
110
|
${services.length > 0 && html`
|