diff --git a/resources/js/admin/logs/components/Logs/AgentSessionDetail/AgentSessionDetail.vue b/resources/js/admin/logs/components/Logs/AgentSessionDetail/AgentSessionDetail.vue
new file mode 100644
index 0000000000..d8a45bbd3c
--- /dev/null
+++ b/resources/js/admin/logs/components/Logs/AgentSessionDetail/AgentSessionDetail.vue
@@ -0,0 +1,929 @@
+
+
+
+
+
+
+
+ {{ sessionData.flow_genie_name || sessionData.agent_name || $t('Session Details') }}
+
+
{{ session.session_id }}
+
+
+
+
+
+ {{ formatStatus(session.status) }}
+
+
+
+
+
+
+
+
+
+
{{ $t('Loading session details...') }}
+
+
+
+
+
+
+
+
+
+
+
{{ $t('Duration') }}
+
+ {{ session.duration || formatDuration(sessionData.execution_time_ms) }}
+
+
+
+
{{ $t('LLM Calls') }}
+
{{ llmCallsCount }}
+
+
+
{{ $t('Tool Calls') }}
+
{{ toolCallsCount }}
+
+
+
{{ $t('Total Tokens') }}
+
+
+
+ {{ session.tokens_used || formatNumber(sessionData.token_usage?.total_tokens) }}
+
+
+
+
+
+
+
+ {{ $t('Input') }}:
+ {{ formatNumber(sessionData.token_usage?.input_tokens) }}
+
+
+ {{ $t('Output') }}:
+ {{ formatNumber(sessionData.token_usage?.output_tokens) }}
+
+
+
+
+
+
+
+
+
+
+
+
{{ $t('No events recorded for this session') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ getEventTypeLabel(event) }}
+ {{ getEventName(event) }}
+
+
+
+ {{ formatDuration(event.duration_ms) }}
+
+
+ {{ formatEventTime(event.timestamp || event.created_at) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ $t('Status') }}
+
+ {{ event.status }}
+
+
+
+
{{ $t('Arguments') }}
+
{{ formatJson(event.arguments || event.input || event.tool_arguments) }}
+
+
+
{{ $t('Output') }}
+
{{ formatJson(event.output || event.result) }}
+
+
+
+
+
+
+
{{ $t('Status') }}
+
+ {{ event.status }}
+
+
+ ({{ event.input_tokens || 0 }} in / {{ event.output_tokens || 0 }} out tokens)
+
+
+
+
{{ $t('Error') }}
+
{{ event.error }}
+
+
+
{{ $t('Input') }}
+
{{ event.input_preview || event.prompt || event.instructions }}
+
+
+
{{ $t('Output') }}
+
{{ event.output_text || event.response || event.output }}
+
+
+
+
+
+
{{ $t('Content') }}
+
{{ event.content }}
+
+
+
+
+
{{ $t('Reasoning') }}
+
{{ event.content }}
+
+
+
+
+
{{ $t('Error Message') }}
+
{{ event.error || event.error_message || event.message || event.data?.error || formatJson(event) }}
+
+
+
+
+
{{ formatJson(event.data || event.details || event) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('Properties') }}
+
+
+
+
+
{{ $t('Session ID') }}
+
{{ session.session_id }}
+
+
+
+
{{ $t('Model') }}
+
{{ sessionData.model || session.model }}
+
+
+
+
{{ $t('User') }}
+
{{ session.user_name }}
+
+
+
+
{{ $t('Started') }}
+
{{ formatFullDateTime(session.created_at) }}
+
+
+
+
{{ $t('Process') }}
+
{{ session.process_name }}
+
+
+
+
{{ $t('Node') }}
+
{{ session.node_name }}
+
+
+
+
+
+
+
+ {{ $t('Resources') }}
+
+
+
+
{{ $t('MCP Servers') }}
+
+
+ {{ server }}
+
+
+
+
+
+
{{ $t('Collections') }}
+
+
+
+
+
+
+
+
+ {{ $t('Configuration') }}
+
+
+
+
+
+
+ {{ $t('Model Settings') }}
+
+
+
+ {{ formatConfigKey(key) }}
+ {{ formatConfigValue(value) }}
+
+
+
+
+
+
+
+ {{ $t('Max Turns') }}
+ {{ sessionData.max_turns }}
+
+
+
+
+
+
+ {{ $t('Instructions') }}
+
+
+ {{ truncateText(configInstructions, 300) }}
+
+
+
+
+
+
+ {{ $t('Request Config') }}
+
+
+
+ {{ formatConfigKey(key) }}
+ {{ formatConfigValue(value) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/js/admin/logs/components/Logs/AgentSessionDetail/index.js b/resources/js/admin/logs/components/Logs/AgentSessionDetail/index.js
new file mode 100644
index 0000000000..01a900019c
--- /dev/null
+++ b/resources/js/admin/logs/components/Logs/AgentSessionDetail/index.js
@@ -0,0 +1,5 @@
+import AgentSessionDetail from "./AgentSessionDetail.vue";
+
+export { AgentSessionDetail };
+export default AgentSessionDetail;
+
diff --git a/resources/js/admin/logs/components/Logs/BaseTable/BaseTable.vue b/resources/js/admin/logs/components/Logs/BaseTable/BaseTable.vue
index f7d42922ff..da4b99b837 100644
--- a/resources/js/admin/logs/components/Logs/BaseTable/BaseTable.vue
+++ b/resources/js/admin/logs/components/Logs/BaseTable/BaseTable.vue
@@ -20,7 +20,12 @@
|
diff --git a/resources/js/admin/logs/components/Logs/HeaderBar/HeaderBar.vue b/resources/js/admin/logs/components/Logs/HeaderBar/HeaderBar.vue
index 4085475684..6878c1c6fc 100644
--- a/resources/js/admin/logs/components/Logs/HeaderBar/HeaderBar.vue
+++ b/resources/js/admin/logs/components/Logs/HeaderBar/HeaderBar.vue
@@ -38,14 +38,14 @@
class="tw-rounded-lg tw-px-3 tw-py-2 tw-text-base"
:class="tabClasses('design')"
>
- {{ $t('Design Mode Logs') }}
+ {{ $t('FlowGenie Studio Logs') }}
- {{ $t('Execution Logs') }}
+ {{ $t('Runtime Logs') }}
@@ -83,6 +83,11 @@ export default {
props: {
value: { type: String, default: '' },
},
+ data() {
+ return {
+ debounceTimer: null,
+ };
+ },
computed: {
isEmailCategory() {
return this.$route.path.startsWith('/email');
@@ -100,6 +105,12 @@ export default {
immediate: true,
},
},
+ beforeDestroy() {
+ // Clear debounce timer when component is destroyed
+ if (this.debounceTimer) {
+ clearTimeout(this.debounceTimer);
+ }
+ },
methods: {
tabClasses(tab) {
const currentRoute = this.$route.params.logType;
@@ -110,9 +121,24 @@ export default {
},
onInput(event) {
this.$emit('input', event.target.value);
+ this.debouncedSearch();
+ },
+ debouncedSearch() {
+ // Clear existing timer
+ if (this.debounceTimer) {
+ clearTimeout(this.debounceTimer);
+ }
+ // Set new timer - wait 300ms after user stops typing
+ this.debounceTimer = setTimeout(() => {
+ this.$emit('search');
+ }, 300);
},
onKeypress(event) {
+ // Allow immediate search on Enter key
if (event.charCode === 13) {
+ if (this.debounceTimer) {
+ clearTimeout(this.debounceTimer);
+ }
this.$emit('search');
}
},
diff --git a/resources/js/admin/logs/components/Logs/LogContainer/LogContainer.vue b/resources/js/admin/logs/components/Logs/LogContainer/LogContainer.vue
index 11cffd54fb..9825c0a42e 100644
--- a/resources/js/admin/logs/components/Logs/LogContainer/LogContainer.vue
+++ b/resources/js/admin/logs/components/Logs/LogContainer/LogContainer.vue
@@ -2,7 +2,10 @@
+
+
+
+
+
+
diff --git a/resources/js/admin/logs/components/Logs/LogTable/LogTable.vue b/resources/js/admin/logs/components/Logs/LogTable/LogTable.vue
index 1de1ff41f1..690552e324 100644
--- a/resources/js/admin/logs/components/Logs/LogTable/LogTable.vue
+++ b/resources/js/admin/logs/components/Logs/LogTable/LogTable.vue
@@ -35,6 +35,10 @@
v-else
:columns="columns"
:data="data"
+ :clickable="isAgentCategory"
+ :selected-item="selectedSession"
+ item-key="session_id"
+ @row-click="handleRowClick"
>
@@ -131,6 +135,8 @@ export default {
totalPages: 1,
perPage: 15,
loading: false,
+ selectedSession: null,
+ currentSearch: '',
};
},
computed: {
@@ -215,15 +221,20 @@ export default {
}
return `/api/1.1/email-start-event/logs/${this.logType}`;
},
+ isAgentCategory() {
+ return this.category === 'agents';
+ },
},
watch: {
category: {
handler() {
+ this.clearSelection();
this.resetAndFetch();
},
},
logType: {
handler() {
+ this.clearSelection();
this.resetAndFetch();
},
immediate: true,
@@ -234,6 +245,7 @@ export default {
this.page = 1;
this.perPage = 15;
this.totalPages = 1;
+ this.currentSearch = '';
this.fetchData();
},
async fetchData(params = {}) {
@@ -263,10 +275,14 @@ export default {
},
handlePageChange(newPage) {
this.page = newPage;
- this.fetchData();
+ this.fetchData({ search: this.currentSearch });
},
refresh(params = {}) {
this.page = 1;
+ // Store search for pagination
+ if (params.search !== undefined) {
+ this.currentSearch = params.search;
+ }
this.fetchData(params);
},
getStatusClasses(status) {
@@ -285,6 +301,16 @@ export default {
};
return statusLabels[status] || status;
},
+ handleRowClick(item) {
+ if (this.isAgentCategory) {
+ this.selectedSession = item;
+ this.$emit('session-selected', item);
+ }
+ },
+ clearSelection() {
+ this.selectedSession = null;
+ this.$emit('session-selected', null);
+ },
},
};
diff --git a/resources/lang/en.json b/resources/lang/en.json
index f95ae63b21..5e07c388e7 100644
--- a/resources/lang/en.json
+++ b/resources/lang/en.json
@@ -908,7 +908,8 @@
"Event": "Event",
"Exclusive Gateway": "Exclusive Gateway",
"Execution Error": "Execution Error",
- "Execution Logs": "Execution Logs",
+ "Runtime Logs": "Runtime Logs",
+ "FlowGenie Studio Logs": "FlowGenie Studio Logs",
"Execution Log": "Execution Log",
"Executor Successfully Built. You can now close this window. ": "Executor Successfully Built. You can now close this window. ",
"Existing Array": "Existing Array",
|