-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add logging of user tier in the telemetry #1132
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
val tier = | ||
if (getIsCurrentUserPro == null) CodyBundle.getString("my-account-tab.loading-label") | ||
else if (getIsCurrentUserPro) CodyBundle.getString("my-account-tab.cody-pro-label") | ||
if (isPro == null) CodyBundle.getString("my-account-tab.loading-label") |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
if (isDotcomAccount()) isProUser(project).thenApply { it.not() } | ||
else CompletableFuture.completedFuture(false) | ||
|
||
fun isProUser(project: Project): CompletableFuture<Boolean> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe deriveIsCurrentUserPro
? to be more precise and reflect the fact that it's not an instant quick "get" but a call to agent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, I just realised - we are caching the pro state now... 🤔
When a user upgrades to pro they are informed that they need to restart the IDE to see the changes. What when a user downgrades to free during the usage?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What when a user downgrades to free during the usage?\
Good question :)
#550
I will address that and some other improvements in a follow-up PR.
else CodyBundle.getString("my-account-tab.cody-free-label") | ||
row { label("<html>Current tier: <b>$tier</b><html/>") } | ||
row { | ||
if (getIsCurrentUserPro != null && !getIsCurrentUserPro) { | ||
if (isPro != null && !isPro) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: isn't that simply isPro == false
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
val upgradeButton = | ||
button("Upgrade") { BrowserUtil.browse(ConfigUtil.DOTCOM_URL + "cody/subscription") } | ||
upgradeButton.component.putClientProperty(DarculaButtonUI.DEFAULT_STYLE_KEY, true) | ||
} | ||
button("Check Usage") { BrowserUtil.browse(ConfigUtil.DOTCOM_URL + "cody/manage") } | ||
} | ||
if (getIsCurrentUserPro != null && !getIsCurrentUserPro) { | ||
if (isPro != null && !isPro) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: isn't that simply isPro == false
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
} | ||
|
||
@RequiresBackgroundThread | ||
private fun ensureUserIdMatchInAgent(jetbrainsUserId: String, server: CodyAgentServer) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so this is redundant? nice 🚀
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tested - indeed it seems to work
return AccountType.ENTERPRISE | ||
@Volatile private var isProUser: Boolean? = null | ||
|
||
fun getAccountType(project: Project): String { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like that change. The difference b/w enterprise and free/pro is different than the difference b/w free and pro. We can call the first category "account type" and the second a "tier". And my feeling is that we are adjusting the model to the telemetry requirements (which feel bad).
If we really need to consider enterprise/free/pro as a same category maybe let's introduce an enum for them. Is AccountType
still needed or should we deprecate it?
Also, if we do the agent call here the method name should be altered to reflect the hidden process - "derive" instead of "get"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can move this code the the logger as it's not user anywhere else so far.
!didSendFirstMessage && !(activeAccountType.isEnterpriseAccount() || model.size <= 1) | ||
val isEnterpriseAccount = | ||
CodyAuthenticationManager.instance.getActiveAccount(project)?.isEnterpriseAccount() ?: false | ||
isEnabled = !didSendFirstMessage && !isEnterpriseAccount && model.size > 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
var event = createEvent(ConfigUtil.getServerPath(project), "CodyInstalled", new JsonObject()); | ||
var event = | ||
createEvent( | ||
project, ConfigUtil.getServerPath(project), "CodyInstalled", new JsonObject()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw, can we have an enum class for the event name? 🙏 it would be easier to navigate b/w then and see which are already in the code in a one place
@@ -65,9 +75,15 @@ private static Event createEvent( | |||
|
|||
@NotNull | |||
private static JsonObject addGlobalEventParameters( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, now I see why we need to cache the tier... 🕵️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just noted new additional entries in the logs:
2024-03-19 23:48:44,484 [ 20502] WARN - #c.s.c.a.CodyAgentClient - Cody by Sourcegraph: █ GraphQLTelemetryExporter: telemetry: failed to evaluate server version: Error: accessing Sourcegraph GraphQL API: Error: HTTP status code 401: Private mode requires authentication.
(https://sg02.sourcegraphcloud.com/.api/graphql?SiteProductVersion)
2024-03-19 23:48:44,867 [ 20885] WARN - #c.s.c.a.CodyAgentClient - Cody by Sourcegraph: █ GraphQLTelemetryExporter: Error exporting telemetry events: Error: accessing Sourcegraph GraphQL API: Error: HTTP status code 401: Private mode requires authentication.
Steps:
runIde
- switch accounts from the settings
I tested it against v5.4.5 - no GraphQLTelemetryExporter
entries there in the same scenario
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's a false alarm - sorry for confusion.
The issue (#454 (comment)) seems to be there already. The two mentioned lines of logs seem to appear when switching to sg02
instance account (in particular).
ea6d66a
to
0fe55e6
Compare
@Service | ||
class CodyAuthenticationManager internal constructor() { | ||
@Service(Service.Level.PROJECT) | ||
class CodyAuthenticationManager(val project: Project) : Disposable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point about revamping it into a project-level service 👍
val accessTokenChanged: Boolean = false | ||
) | ||
val accessTokenChanged: Boolean = false, | ||
val accountTierChanged: Boolean = false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💟
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but it's unused 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was added mostly for clarity so e.g. in debugger when you will notice AccountSettingChangeContext
it will be clear why it was emitted. With just two other properties set to false it could look like a bug.
class LlmDropdown( | ||
private val project: Project, | ||
private val onSetSelectedItem: (ChatModelsResponse.ChatModelProvider) -> Unit, | ||
private val chatModelProviderFromState: ChatModelsResponse.ChatModelProvider?, | ||
) : ComboBox<ChatModelsResponse.ChatModelProvider>(MutableCollectionComboBoxModel()) { | ||
|
||
private var didSendFirstMessage: Boolean = false | ||
var isCurrentUserFree = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
iirc that is the place you mentioned - the scenario is that a user has an open chat with no message in and changes their account tier - that change will not be reflected in the dropdown. is that right?
can you please put a comment on this field? this place looks a bit extraordinary compared to the rest of the codebase after your changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should just fix it, I kind of forgot about it afterwards.
val activeAccount = accountsModel.activeAccount | ||
activeAccountHolder.account = activeAccount |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
iiuc this logic (setting the active account in the holder) is executed anyway by CodyAuthenticationManager.getInstance(project).setActiveAccount(activeAccount)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct
agent.server.configurationDidChange(ConfigUtil.getAgentConfiguration(project)) | ||
} | ||
CodyAgentService.getInstance(project).restartAgent(project) | ||
if (ConfigUtil.isCodyEnabled() && context.accountChanged()) { | ||
CodyToolWindowContent.executeOnInstanceIfNotDisposed(project) { | ||
removeAllChatSessions() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, if I change the token it makes accountChanged == true
but that is not necessarily mean the account changed - I mean - I can change my own token to another token of the same account
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should adjust the name. accountConfigurationChanged
?
27ded74
to
9602860
Compare
9602860
to
5a01768
Compare
Fixes:
#550
sourcegraph/cody#2467
Changes
CodyAccount::getActiveAccountTier
method with result caching.GraphQlLogger
CodyAccount::setActiveAccount
)CodyAuthenticationManager::init
)Test plan
Manual verification if proper entries are in the GraphQL