Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions backend/plugins/kiro/api/test_connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ func TestExistingConnection(input *plugin.ApiResourceInput) (*plugin.ApiResource
// discovered accounts and per-stream object counts makes the difference visible
// before any scope is created.
type ConnectionReport struct {
// Success and Message satisfy the shared Config UI connection-test contract.
// The detailed fields below remain available to explain an empty export.
Success bool `json:"success"`
Message string `json:"message"`

ReportBucket string `json:"reportBucket"`
PromptLogBucket string `json:"promptLogBucket"`
// Accounts are the AWS account ids found under the report prefix. An empty
Expand All @@ -111,18 +116,24 @@ type ConnectionReport struct {
// verifying a path - only whether it is zero.
const connectionReportCountLimit = 500

func newConnectionReport(connection *models.KiroConnection) *ConnectionReport {
return &ConnectionReport{
Success: true,
Message: "success",
ReportBucket: connection.Bucket,
PromptLogBucket: connection.GetPromptLogBucket(),
Accounts: []string{},
Streams: []tasks.StreamCount{},
}
}

// buildConnectionReport probes the layout and summarizes what was found.
//
// Errors are folded into the report rather than returned: the connection itself
// is already known to work at this point, and a discovery failure is more useful
// shown as an empty result with a hint than as a failed request.
func buildConnectionReport(connection *models.KiroConnection) *ConnectionReport {
report := &ConnectionReport{
ReportBucket: connection.Bucket,
PromptLogBucket: connection.GetPromptLogBucket(),
Accounts: []string{},
Streams: []tasks.StreamCount{},
}
report := newConnectionReport(connection)

discovery, err := tasks.NewDiscovery(connection)
if err != nil {
Expand Down
56 changes: 56 additions & 0 deletions backend/plugins/kiro/api/test_connection_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package api

import (
"encoding/json"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/apache/incubator-devlake/plugins/kiro/models"
)

func TestNewConnectionReportSatisfiesConfigUIContract(t *testing.T) {
connection := &models.KiroConnection{
KiroConn: models.KiroConn{
Bucket: "report-bucket",
PromptLogBucket: "log-bucket",
},
}

report := newConnectionReport(connection)
assert.True(t, report.Success)
assert.Equal(t, "success", report.Message)
assert.Equal(t, "report-bucket", report.ReportBucket)
assert.Equal(t, "log-bucket", report.PromptLogBucket)
assert.NotNil(t, report.Accounts)
assert.NotNil(t, report.Streams)

body, err := json.Marshal(report)
require.NoError(t, err)
assert.JSONEq(t, `{
"success": true,
"message": "success",
"reportBucket": "report-bucket",
"promptLogBucket": "log-bucket",
"accounts": [],
"streams": []
}`, string(body))
}
10 changes: 5 additions & 5 deletions grafana/dashboards/postgresql/kiro_executive.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@
"editorMode": "code",
"format": "table",
"rawQuery": true,
"rawSql": "SELECT COUNT(DISTINCT user_id) AS \"WAU\" FROM lake._tool_kiro_chat_log WHERE timestamp >= NOW() - INTERVAL '7 DAY'",
"rawSql": "SELECT COUNT(DISTINCT user_id) AS \"WAU\" FROM _tool_kiro_chat_log WHERE timestamp >= NOW() - INTERVAL '7 DAY'",
"refId": "A"
}
],
Expand Down Expand Up @@ -322,7 +322,7 @@
"editorMode": "code",
"format": "table",
"rawQuery": true,
"rawSql": "SELECT ROUND(CAST(CAST(COUNT(DISTINCT CASE WHEN has_steering = TRUE THEN user_id END) AS NUMERIC) / NULLIF(NULLIF(COUNT(DISTINCT user_id), 0), 0) * 100 AS DECIMAL), 0) AS \"Steering %\" FROM lake._tool_kiro_chat_log WHERE $__timeFilter(timestamp)",
"rawSql": "SELECT ROUND(CAST(CAST(COUNT(DISTINCT CASE WHEN has_steering = TRUE THEN user_id END) AS NUMERIC) / NULLIF(NULLIF(COUNT(DISTINCT user_id), 0), 0) * 100 AS DECIMAL), 0) AS \"Steering %\" FROM _tool_kiro_chat_log WHERE $__timeFilter(timestamp)",
"refId": "A"
}
],
Expand Down Expand Up @@ -433,7 +433,7 @@
"editorMode": "code",
"format": "time_series",
"rawQuery": true,
"rawSql": "SELECT TO_DATE(yw || ' Monday', 'IYYYIW FMDay') AS time, COUNT(DISTINCT user_id) AS \"Active Users\" FROM (SELECT user_id, (EXTRACT(ISOYEAR FROM timestamp) * 100 + EXTRACT(WEEK FROM timestamp))::int AS yw FROM lake._tool_kiro_chat_log WHERE $__timeFilter(timestamp)) AS t GROUP BY \"yw\" ORDER BY time NULLS FIRST",
"rawSql": "SELECT TO_DATE(yw || ' Monday', 'IYYYIW FMDay') AS time, COUNT(DISTINCT user_id) AS \"Active Users\" FROM (SELECT user_id, (EXTRACT(ISOYEAR FROM timestamp) * 100 + EXTRACT(WEEK FROM timestamp))::int AS yw FROM _tool_kiro_chat_log WHERE $__timeFilter(timestamp)) AS t GROUP BY \"yw\" ORDER BY time NULLS FIRST",
"refId": "A"
}
],
Expand Down Expand Up @@ -642,7 +642,7 @@
"editorMode": "code",
"format": "time_series",
"rawQuery": true,
"rawSql": "SELECT date AS time, SUM(SUM(credits_used)) OVER (ORDER BY date NULLS FIRST) AS \"Cumulative Credits\", (SELECT CAST(SUM(credits_used) AS NUMERIC) / NULLIF(COUNT(DISTINCT date), 0) * EXTRACT(DAY FROM CAST(CAST(DATE_TRUNC('MONTH', CURRENT_DATE) + INTERVAL '1 MONTH' - INTERVAL '1 DAY' AS DATE) AS DATE)) FROM lake._tool_kiro_user_report WHERE YEAR(CAST(date AS DATE)) = YEAR(CAST(CURRENT_DATE AS DATE)) AND MONTH(CAST(date AS DATE)) = MONTH(CAST(CURRENT_DATE AS DATE))) AS \"Projected Monthly\" FROM lake._tool_kiro_user_report WHERE YEAR(CAST(date AS DATE)) = YEAR(CAST(CURRENT_DATE AS DATE)) AND MONTH(CAST(date AS DATE)) = MONTH(CAST(CURRENT_DATE AS DATE)) GROUP BY \"date\" ORDER BY date NULLS FIRST",
"rawSql": "SELECT date AS time, SUM(SUM(credits_used)) OVER (ORDER BY date NULLS FIRST) AS \"Cumulative Credits\", (SELECT CAST(SUM(credits_used) AS NUMERIC) / NULLIF(COUNT(DISTINCT date), 0) * EXTRACT(DAY FROM CAST(CAST(DATE_TRUNC('MONTH', CURRENT_DATE) + INTERVAL '1 MONTH' - INTERVAL '1 DAY' AS DATE) AS DATE)) FROM _tool_kiro_user_report WHERE EXTRACT(YEAR FROM date) = EXTRACT(YEAR FROM CURRENT_DATE) AND EXTRACT(MONTH FROM date) = EXTRACT(MONTH FROM CURRENT_DATE)) AS \"Projected Monthly\" FROM _tool_kiro_user_report WHERE EXTRACT(YEAR FROM date) = EXTRACT(YEAR FROM CURRENT_DATE) AND EXTRACT(MONTH FROM date) = EXTRACT(MONTH FROM CURRENT_DATE) GROUP BY \"date\" ORDER BY date NULLS FIRST",
"refId": "A"
}
],
Expand Down Expand Up @@ -710,7 +710,7 @@
"editorMode": "code",
"format": "table",
"rawQuery": true,
"rawSql": "SELECT COALESCE(MAX(display_name), user_id) AS \"User\", MAX(subscription_tier) AS \"Tier\", ROUND(SUM(credits_used), 1) AS \"Total Credits Used\", MAX(date) AS \"Last Activity\" FROM lake._tool_kiro_user_report WHERE $__timeFilter(date) AND subscription_tier = 'POWER' GROUP BY \"user_id\" HAVING MAX(date) < NOW() - INTERVAL '14 DAY' ORDER BY MAX(date) NULLS FIRST",
"rawSql": "SELECT COALESCE(MAX(display_name), user_id) AS \"User\", MAX(subscription_tier) AS \"Tier\", ROUND(SUM(credits_used), 1) AS \"Total Credits Used\", MAX(date) AS \"Last Activity\" FROM _tool_kiro_user_report WHERE $__timeFilter(date) AND subscription_tier = 'POWER' GROUP BY \"user_id\" HAVING MAX(date) < NOW() - INTERVAL '14 DAY' ORDER BY MAX(date) NULLS FIRST",
"refId": "A"
}
],
Expand Down
14 changes: 7 additions & 7 deletions grafana/dashboards/postgresql/kiro_logging.json
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@
"editorMode": "code",
"format": "table",
"rawQuery": true,
"rawSql": "SELECT LPAD(CAST(hour_of_day AS TEXT), 2, '0') AS \"Hour\", SUM(chat_count) AS \"Chat Events\", SUM(completion_count) AS \"Completion Events\" FROM (SELECT EXTRACT(HOUR FROM timestamp) AS hour_of_day, COUNT(*) AS chat_count, 0 AS completion_count FROM lake._tool_kiro_chat_log WHERE $__timeFilter(timestamp) GROUP BY EXTRACT(HOUR FROM timestamp) UNION ALL SELECT EXTRACT(HOUR FROM timestamp) AS hour_of_day, 0 AS chat_count, COUNT(*) AS completion_count FROM lake._tool_kiro_completion_log WHERE $__timeFilter(timestamp) GROUP BY EXTRACT(HOUR FROM timestamp)) AS combined GROUP BY hour_of_day ORDER BY hour_of_day NULLS FIRST",
"rawSql": "SELECT LPAD(CAST(hour_of_day AS TEXT), 2, '0') AS \"Hour\", SUM(chat_count) AS \"Chat Events\", SUM(completion_count) AS \"Completion Events\" FROM (SELECT EXTRACT(HOUR FROM timestamp) AS hour_of_day, COUNT(*) AS chat_count, 0 AS completion_count FROM _tool_kiro_chat_log WHERE $__timeFilter(timestamp) GROUP BY EXTRACT(HOUR FROM timestamp) UNION ALL SELECT EXTRACT(HOUR FROM timestamp) AS hour_of_day, 0 AS chat_count, COUNT(*) AS completion_count FROM _tool_kiro_completion_log WHERE $__timeFilter(timestamp) GROUP BY EXTRACT(HOUR FROM timestamp)) AS combined GROUP BY hour_of_day ORDER BY hour_of_day NULLS FIRST",
"refId": "A"
}
],
Expand Down Expand Up @@ -245,7 +245,7 @@
"editorMode": "code",
"format": "table",
"rawQuery": true,
"rawSql": "SELECT CASE WHEN chat_trigger_type = '' OR chat_trigger_type IS NULL THEN '(unknown)' ELSE chat_trigger_type END AS \"Trigger Type\", COUNT(*) AS \"Events\" FROM lake._tool_kiro_chat_log WHERE $__timeFilter(timestamp) GROUP BY \"chat_trigger_type\" ORDER BY COUNT(*) DESC NULLS LAST",
"rawSql": "SELECT CASE WHEN chat_trigger_type = '' OR chat_trigger_type IS NULL THEN '(unknown)' ELSE chat_trigger_type END AS \"Trigger Type\", COUNT(*) AS \"Events\" FROM _tool_kiro_chat_log WHERE $__timeFilter(timestamp) GROUP BY \"chat_trigger_type\" ORDER BY COUNT(*) DESC NULLS LAST",
"refId": "A"
}
],
Expand Down Expand Up @@ -393,7 +393,7 @@
"editorMode": "code",
"format": "table",
"rawQuery": true,
"rawSql": "SELECT CASE WHEN file_extension = '' THEN '(unknown)' ELSE file_extension END AS \"File Type\", COUNT(*) AS \"Completions\" FROM lake._tool_kiro_completion_log WHERE $__timeFilter(timestamp) GROUP BY \"file_extension\" ORDER BY COUNT(*) DESC NULLS LAST LIMIT 15",
"rawSql": "SELECT CASE WHEN file_extension = '' THEN '(unknown)' ELSE file_extension END AS \"File Type\", COUNT(*) AS \"Completions\" FROM _tool_kiro_completion_log WHERE $__timeFilter(timestamp) GROUP BY \"file_extension\" ORDER BY COUNT(*) DESC NULLS LAST LIMIT 15",
"refId": "A"
}
],
Expand Down Expand Up @@ -589,7 +589,7 @@
"editorMode": "code",
"format": "time_series",
"rawQuery": true,
"rawSql": "SELECT time, SUM(chat) AS \"Chat Events\", SUM(completions) AS \"Completion Events\" FROM (SELECT CAST(timestamp AS DATE) AS time, COUNT(*) AS chat, 0 AS completions FROM lake._tool_kiro_chat_log WHERE $__timeFilter(timestamp) GROUP BY CAST(timestamp AS DATE) UNION ALL SELECT CAST(timestamp AS DATE) AS time, 0 AS chat, COUNT(*) AS completions FROM lake._tool_kiro_completion_log WHERE $__timeFilter(timestamp) GROUP BY CAST(timestamp AS DATE)) AS combined GROUP BY time ORDER BY time NULLS FIRST",
"rawSql": "SELECT time, SUM(chat) AS \"Chat Events\", SUM(completions) AS \"Completion Events\" FROM (SELECT CAST(timestamp AS DATE) AS time, COUNT(*) AS chat, 0 AS completions FROM _tool_kiro_chat_log WHERE $__timeFilter(timestamp) GROUP BY CAST(timestamp AS DATE) UNION ALL SELECT CAST(timestamp AS DATE) AS time, 0 AS chat, COUNT(*) AS completions FROM _tool_kiro_completion_log WHERE $__timeFilter(timestamp) GROUP BY CAST(timestamp AS DATE)) AS combined GROUP BY time ORDER BY time NULLS FIRST",
"refId": "A"
}
],
Expand Down Expand Up @@ -731,7 +731,7 @@
"editorMode": "code",
"format": "table",
"rawQuery": true,
"rawSql": "SELECT SUM(CASE WHEN has_steering = TRUE THEN 1 ELSE 0 END) AS \"Using Steering\", SUM(CASE WHEN is_spec_mode = TRUE THEN 1 ELSE 0 END) AS \"Using Spec Mode\", SUM(CASE WHEN has_steering = FALSE AND is_spec_mode = FALSE THEN 1 ELSE 0 END) AS \"Plain Chat\" FROM lake._tool_kiro_chat_log WHERE $__timeFilter(timestamp)",
"rawSql": "SELECT SUM(CASE WHEN has_steering = TRUE THEN 1 ELSE 0 END) AS \"Using Steering\", SUM(CASE WHEN is_spec_mode = TRUE THEN 1 ELSE 0 END) AS \"Using Spec Mode\", SUM(CASE WHEN has_steering = FALSE AND is_spec_mode = FALSE THEN 1 ELSE 0 END) AS \"Plain Chat\" FROM _tool_kiro_chat_log WHERE $__timeFilter(timestamp)",
"refId": "A"
}
],
Expand Down Expand Up @@ -977,7 +977,7 @@
"editorMode": "code",
"format": "time_series",
"rawQuery": true,
"rawSql": "SELECT CAST(timestamp AS DATE) AS time, AVG(prompt_length) AS \"Avg Prompt Length\", AVG(response_length) AS \"Avg Response Length\", MAX(prompt_length) AS \"Max Prompt Length\", MAX(response_length) AS \"Max Response Length\" FROM lake._tool_kiro_chat_log WHERE $__timeFilter(timestamp) GROUP BY CAST(timestamp AS DATE) ORDER BY CAST(timestamp AS DATE) NULLS FIRST",
"rawSql": "SELECT CAST(timestamp AS DATE) AS time, AVG(prompt_length) AS \"Avg Prompt Length\", AVG(response_length) AS \"Avg Response Length\", MAX(prompt_length) AS \"Max Prompt Length\", MAX(response_length) AS \"Max Response Length\" FROM _tool_kiro_chat_log WHERE $__timeFilter(timestamp) GROUP BY CAST(timestamp AS DATE) ORDER BY CAST(timestamp AS DATE) NULLS FIRST",
"refId": "A"
}
],
Expand Down Expand Up @@ -1074,7 +1074,7 @@
"editorMode": "code",
"format": "time_series",
"rawQuery": true,
"rawSql": "SELECT CAST(timestamp AS DATE) AS time, ROUND(AVG(left_context_length)) AS \"Avg Left Context\", ROUND(AVG(right_context_length)) AS \"Avg Right Context\", ROUND(AVG(left_context_length + right_context_length)) AS \"Avg Total Context\" FROM lake._tool_kiro_completion_log WHERE $__timeFilter(timestamp) GROUP BY CAST(timestamp AS DATE) ORDER BY CAST(timestamp AS DATE) NULLS FIRST",
"rawSql": "SELECT CAST(timestamp AS DATE) AS time, ROUND(AVG(left_context_length)) AS \"Avg Left Context\", ROUND(AVG(right_context_length)) AS \"Avg Right Context\", ROUND(AVG(left_context_length + right_context_length)) AS \"Avg Total Context\" FROM _tool_kiro_completion_log WHERE $__timeFilter(timestamp) GROUP BY CAST(timestamp AS DATE) ORDER BY CAST(timestamp AS DATE) NULLS FIRST",
"refId": "A"
}
],
Expand Down
8 changes: 4 additions & 4 deletions grafana/dashboards/postgresql/kiro_user_report.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
"editorMode": "code",
"format": "table",
"rawQuery": true,
"rawSql": "SELECT SUM(credits_used) AS \"Total Credits Used\", COUNT(DISTINCT user_id) AS \"Active Users\", SUM(total_messages) AS \"Total Messages\", SUM(chat_conversations) AS \"Total Conversations\" FROM lake._tool_kiro_user_report WHERE $__timeFilter(date)",
"rawSql": "SELECT SUM(credits_used) AS \"Total Credits Used\", COUNT(DISTINCT user_id) AS \"Active Users\", SUM(total_messages) AS \"Total Messages\", SUM(chat_conversations) AS \"Total Conversations\" FROM _tool_kiro_user_report WHERE $__timeFilter(date)",
"refId": "A"
}
],
Expand Down Expand Up @@ -174,7 +174,7 @@
"editorMode": "code",
"format": "time_series",
"rawQuery": true,
"rawSql": "SELECT date AS time, subscription_tier AS metric, SUM(credits_used) AS value FROM lake._tool_kiro_user_report WHERE $__timeFilter(date) GROUP BY \"date\", \"subscription_tier\" ORDER BY date NULLS FIRST",
"rawSql": "SELECT date AS time, subscription_tier AS metric, SUM(credits_used) AS value FROM _tool_kiro_user_report WHERE $__timeFilter(date) GROUP BY \"date\", \"subscription_tier\" ORDER BY date NULLS FIRST",
"refId": "A"
}
],
Expand Down Expand Up @@ -346,7 +346,7 @@
"editorMode": "code",
"format": "table",
"rawQuery": true,
"rawSql": "SELECT subscription_tier AS \"Tier\", COUNT(DISTINCT user_id) AS \"Users\" FROM lake._tool_kiro_user_report WHERE $__timeFilter(date) AND NOT subscription_tier IS NULL AND subscription_tier <> '' GROUP BY \"subscription_tier\" ORDER BY COUNT(DISTINCT user_id) DESC NULLS LAST",
"rawSql": "SELECT subscription_tier AS \"Tier\", COUNT(DISTINCT user_id) AS \"Users\" FROM _tool_kiro_user_report WHERE $__timeFilter(date) AND NOT subscription_tier IS NULL AND subscription_tier <> '' GROUP BY \"subscription_tier\" ORDER BY COUNT(DISTINCT user_id) DESC NULLS LAST",
"refId": "A"
}
],
Expand Down Expand Up @@ -463,7 +463,7 @@
"editorMode": "code",
"format": "table",
"rawQuery": true,
"rawSql": "SELECT COALESCE(MAX(display_name), user_id) AS \"User\", subscription_tier AS \"Tier\", client_type AS \"Client\", SUM(credits_used) AS \"Credits Used\", SUM(total_messages) AS \"Messages\", SUM(chat_conversations) AS \"Conversations\", SUM(overage_credits_used) AS \"Overage Credits\", CASE WHEN MAX(CAST(overage_enabled AS BIGINT)) = 1 THEN 'Yes' ELSE 'No' END AS \"Overage\", MIN(date) AS \"First Activity\", MAX(date) AS \"Last Activity\" FROM lake._tool_kiro_user_report WHERE $__timeFilter(date) GROUP BY \"user_id\", \"subscription_tier\", \"client_type\" ORDER BY user_id DESC NULLS LAST",
"rawSql": "SELECT COALESCE(MAX(display_name), user_id) AS \"User\", subscription_tier AS \"Tier\", client_type AS \"Client\", SUM(credits_used) AS \"Credits Used\", SUM(total_messages) AS \"Messages\", SUM(chat_conversations) AS \"Conversations\", SUM(overage_credits_used) AS \"Overage Credits\", CASE WHEN BOOL_OR(overage_enabled) THEN 'Yes' ELSE 'No' END AS \"Overage\", MIN(date) AS \"First Activity\", MAX(date) AS \"Last Activity\" FROM _tool_kiro_user_report WHERE $__timeFilter(date) GROUP BY \"user_id\", \"subscription_tier\", \"client_type\" ORDER BY user_id DESC NULLS LAST",
"refId": "A"
}
],
Expand Down
Loading