mirror of
https://github.com/openai/codex.git
synced 2026-11-01 19:33:35 +00:00
Generalize product analytics event tracking
This commit is contained in:
@@ -66,6 +66,7 @@ use codex_app_server_protocol::InitializeParams;
|
||||
use codex_app_server_protocol::JSONRPCErrorError;
|
||||
use codex_app_server_protocol::NonSteerableTurnKind;
|
||||
use codex_app_server_protocol::PermissionProfile as AppServerPermissionProfile;
|
||||
use codex_app_server_protocol::ProductAnalyticsEvent;
|
||||
use codex_app_server_protocol::RequestId;
|
||||
use codex_app_server_protocol::SandboxPolicy as AppServerSandboxPolicy;
|
||||
use codex_app_server_protocol::ServerNotification;
|
||||
@@ -74,8 +75,7 @@ use codex_app_server_protocol::Thread;
|
||||
use codex_app_server_protocol::ThreadResumeResponse;
|
||||
use codex_app_server_protocol::ThreadStartResponse;
|
||||
use codex_app_server_protocol::ThreadStatus as AppServerThreadStatus;
|
||||
use codex_app_server_protocol::TrackUsageLimitBannerAction;
|
||||
use codex_app_server_protocol::TrackUsageLimitBannerParams;
|
||||
use codex_app_server_protocol::TrackProductAnalyticsEventParams;
|
||||
use codex_app_server_protocol::Turn;
|
||||
use codex_app_server_protocol::TurnCompletedNotification;
|
||||
use codex_app_server_protocol::TurnError as AppServerTurnError;
|
||||
@@ -84,6 +84,7 @@ use codex_app_server_protocol::TurnStartedNotification;
|
||||
use codex_app_server_protocol::TurnStatus as AppServerTurnStatus;
|
||||
use codex_app_server_protocol::TurnSteerParams;
|
||||
use codex_app_server_protocol::TurnSteerResponse;
|
||||
use codex_app_server_protocol::UsageLimitBannerAction;
|
||||
use codex_app_server_protocol::UsageLimitBannerType;
|
||||
use codex_app_server_protocol::UserInput;
|
||||
use codex_login::default_client::DEFAULT_ORIGINATOR;
|
||||
@@ -2417,11 +2418,13 @@ async fn usage_limit_banner_shown_request_emits_credits_event() {
|
||||
AnalyticsFact::Request {
|
||||
connection_id: 7,
|
||||
request_id: RequestId::Integer(1),
|
||||
request: Box::new(ClientRequest::TrackUsageLimitBanner {
|
||||
request: Box::new(ClientRequest::TrackProductAnalyticsEvent {
|
||||
request_id: RequestId::Integer(1),
|
||||
params: TrackUsageLimitBannerParams {
|
||||
action: TrackUsageLimitBannerAction::Shown,
|
||||
banner_type: UsageLimitBannerType::WorkspaceMemberCreditsDepleted,
|
||||
params: TrackProductAnalyticsEventParams {
|
||||
event: ProductAnalyticsEvent::UsageLimitBanner {
|
||||
action: UsageLimitBannerAction::Shown,
|
||||
banner_type: UsageLimitBannerType::WorkspaceMemberCreditsDepleted,
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
@@ -2453,11 +2456,13 @@ async fn usage_limit_banner_click_request_emits_usage_limit_event() {
|
||||
AnalyticsFact::Request {
|
||||
connection_id: 7,
|
||||
request_id: RequestId::Integer(1),
|
||||
request: Box::new(ClientRequest::TrackUsageLimitBanner {
|
||||
request: Box::new(ClientRequest::TrackProductAnalyticsEvent {
|
||||
request_id: RequestId::Integer(1),
|
||||
params: TrackUsageLimitBannerParams {
|
||||
action: TrackUsageLimitBannerAction::CtaClicked,
|
||||
banner_type: UsageLimitBannerType::WorkspaceMemberUsageLimitReached,
|
||||
params: TrackProductAnalyticsEventParams {
|
||||
event: ProductAnalyticsEvent::UsageLimitBanner {
|
||||
action: UsageLimitBannerAction::CtaClicked,
|
||||
banner_type: UsageLimitBannerType::WorkspaceMemberUsageLimitReached,
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
|
||||
@@ -20,8 +20,7 @@ use crate::facts::TurnSteerResult;
|
||||
use crate::facts::TurnSubmissionType;
|
||||
use crate::now_unix_seconds;
|
||||
use codex_app_server_protocol::CodexErrorInfo;
|
||||
use codex_app_server_protocol::TrackUsageLimitBannerAction;
|
||||
use codex_app_server_protocol::TrackUsageLimitBannerParams;
|
||||
use codex_app_server_protocol::UsageLimitBannerAction;
|
||||
use codex_app_server_protocol::UsageLimitBannerType;
|
||||
use codex_login::default_client::originator;
|
||||
use codex_plugin::PluginTelemetryMetadata;
|
||||
@@ -591,35 +590,36 @@ pub(crate) fn plugin_state_event_type(state: PluginState) -> &'static str {
|
||||
}
|
||||
|
||||
pub(crate) fn usage_limit_banner_event_request(
|
||||
params: TrackUsageLimitBannerParams,
|
||||
action: UsageLimitBannerAction,
|
||||
banner_type: UsageLimitBannerType,
|
||||
) -> UsageLimitBannerEventRequest {
|
||||
let limit_reason = match params.banner_type {
|
||||
let limit_reason = match banner_type {
|
||||
UsageLimitBannerType::WorkspaceMemberCreditsDepleted => "credits",
|
||||
UsageLimitBannerType::WorkspaceMemberUsageLimitReached => "usage_limit",
|
||||
};
|
||||
let banner_type = match params.banner_type {
|
||||
let banner_type_param = match banner_type {
|
||||
UsageLimitBannerType::WorkspaceMemberCreditsDepleted => "workspace_member_credits_depleted",
|
||||
UsageLimitBannerType::WorkspaceMemberUsageLimitReached => {
|
||||
"workspace_member_usage_limit_reached"
|
||||
}
|
||||
};
|
||||
let cta_action = match params.banner_type {
|
||||
let cta_action = match banner_type {
|
||||
UsageLimitBannerType::WorkspaceMemberCreditsDepleted => "notify_owner",
|
||||
UsageLimitBannerType::WorkspaceMemberUsageLimitReached => "request_increase",
|
||||
};
|
||||
let cta_action = match params.action {
|
||||
TrackUsageLimitBannerAction::Shown => None,
|
||||
TrackUsageLimitBannerAction::CtaClicked => Some(cta_action),
|
||||
let cta_action = match action {
|
||||
UsageLimitBannerAction::Shown => None,
|
||||
UsageLimitBannerAction::CtaClicked => Some(cta_action),
|
||||
};
|
||||
|
||||
UsageLimitBannerEventRequest {
|
||||
event_type: match params.action {
|
||||
TrackUsageLimitBannerAction::Shown => "codex_usage_limit_banner_shown",
|
||||
TrackUsageLimitBannerAction::CtaClicked => "codex_usage_limit_banner_cta_clicked",
|
||||
event_type: match action {
|
||||
UsageLimitBannerAction::Shown => "codex_usage_limit_banner_shown",
|
||||
UsageLimitBannerAction::CtaClicked => "codex_usage_limit_banner_cta_clicked",
|
||||
},
|
||||
event_params: UsageLimitBannerEventParams {
|
||||
platform: "codex_cli",
|
||||
banner_type,
|
||||
banner_type: banner_type_param,
|
||||
limit_reason,
|
||||
cta_action,
|
||||
},
|
||||
|
||||
@@ -52,6 +52,7 @@ use codex_app_server_protocol::ClientRequest;
|
||||
use codex_app_server_protocol::ClientResponse;
|
||||
use codex_app_server_protocol::CodexErrorInfo;
|
||||
use codex_app_server_protocol::InitializeParams;
|
||||
use codex_app_server_protocol::ProductAnalyticsEvent;
|
||||
use codex_app_server_protocol::RequestId;
|
||||
use codex_app_server_protocol::ServerNotification;
|
||||
use codex_app_server_protocol::TurnSteerResponse;
|
||||
@@ -333,10 +334,17 @@ impl AnalyticsReducer {
|
||||
}),
|
||||
);
|
||||
}
|
||||
ClientRequest::TrackUsageLimitBanner { params, .. } => {
|
||||
out.push(TrackEventRequest::UsageLimitBanner(
|
||||
usage_limit_banner_event_request(params),
|
||||
));
|
||||
ClientRequest::TrackProductAnalyticsEvent { params, .. } => {
|
||||
let event = match params.event {
|
||||
ProductAnalyticsEvent::UsageLimitBanner {
|
||||
action,
|
||||
banner_type,
|
||||
} => TrackEventRequest::UsageLimitBanner(usage_limit_banner_event_request(
|
||||
action,
|
||||
banner_type,
|
||||
)),
|
||||
};
|
||||
out.push(event);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
+43
-19
@@ -2126,6 +2126,34 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ProductAnalyticsEvent": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"action": {
|
||||
"$ref": "#/definitions/UsageLimitBannerAction"
|
||||
},
|
||||
"bannerType": {
|
||||
"$ref": "#/definitions/UsageLimitBannerType"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"usageLimitBanner"
|
||||
],
|
||||
"title": "UsageLimitBannerProductAnalyticsEventType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action",
|
||||
"bannerType",
|
||||
"type"
|
||||
],
|
||||
"title": "UsageLimitBannerProductAnalyticsEvent",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"RealtimeOutputModality": {
|
||||
"enum": [
|
||||
"text",
|
||||
@@ -4082,25 +4110,14 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"TrackUsageLimitBannerAction": {
|
||||
"enum": [
|
||||
"shown",
|
||||
"cta_clicked"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"TrackUsageLimitBannerParams": {
|
||||
"TrackProductAnalyticsEventParams": {
|
||||
"properties": {
|
||||
"action": {
|
||||
"$ref": "#/definitions/TrackUsageLimitBannerAction"
|
||||
},
|
||||
"bannerType": {
|
||||
"$ref": "#/definitions/UsageLimitBannerType"
|
||||
"event": {
|
||||
"$ref": "#/definitions/ProductAnalyticsEvent"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action",
|
||||
"bannerType"
|
||||
"event"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
@@ -4287,6 +4304,13 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"UsageLimitBannerAction": {
|
||||
"enum": [
|
||||
"shown",
|
||||
"cta_clicked"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"UsageLimitBannerType": {
|
||||
"enum": [
|
||||
"workspace_member_credits_depleted",
|
||||
@@ -5843,13 +5867,13 @@
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"account/usageLimitBanner/track"
|
||||
"analytics/productEvent/track"
|
||||
],
|
||||
"title": "Account/usageLimitBanner/trackRequestMethod",
|
||||
"title": "Analytics/productEvent/trackRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/TrackUsageLimitBannerParams"
|
||||
"$ref": "#/definitions/TrackProductAnalyticsEventParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -5857,7 +5881,7 @@
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Account/usageLimitBanner/trackRequest",
|
||||
"title": "Analytics/productEvent/trackRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
|
||||
+46
-22
@@ -1582,13 +1582,13 @@
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"account/usageLimitBanner/track"
|
||||
"analytics/productEvent/track"
|
||||
],
|
||||
"title": "Account/usageLimitBanner/trackRequestMethod",
|
||||
"title": "Analytics/productEvent/trackRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/v2/TrackUsageLimitBannerParams"
|
||||
"$ref": "#/definitions/v2/TrackProductAnalyticsEventParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -1596,7 +1596,7 @@
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Account/usageLimitBanner/trackRequest",
|
||||
"title": "Analytics/productEvent/trackRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
@@ -12063,6 +12063,34 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ProductAnalyticsEvent": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"action": {
|
||||
"$ref": "#/definitions/v2/UsageLimitBannerAction"
|
||||
},
|
||||
"bannerType": {
|
||||
"$ref": "#/definitions/v2/UsageLimitBannerType"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"usageLimitBanner"
|
||||
],
|
||||
"title": "UsageLimitBannerProductAnalyticsEventType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action",
|
||||
"bannerType",
|
||||
"type"
|
||||
],
|
||||
"title": "UsageLimitBannerProductAnalyticsEvent",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ProfileV2": {
|
||||
"additionalProperties": true,
|
||||
"properties": {
|
||||
@@ -16917,33 +16945,22 @@
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"TrackUsageLimitBannerAction": {
|
||||
"enum": [
|
||||
"shown",
|
||||
"cta_clicked"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"TrackUsageLimitBannerParams": {
|
||||
"TrackProductAnalyticsEventParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"action": {
|
||||
"$ref": "#/definitions/v2/TrackUsageLimitBannerAction"
|
||||
},
|
||||
"bannerType": {
|
||||
"$ref": "#/definitions/v2/UsageLimitBannerType"
|
||||
"event": {
|
||||
"$ref": "#/definitions/v2/ProductAnalyticsEvent"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action",
|
||||
"bannerType"
|
||||
"event"
|
||||
],
|
||||
"title": "TrackUsageLimitBannerParams",
|
||||
"title": "TrackProductAnalyticsEventParams",
|
||||
"type": "object"
|
||||
},
|
||||
"TrackUsageLimitBannerResponse": {
|
||||
"TrackProductAnalyticsEventResponse": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "TrackUsageLimitBannerResponse",
|
||||
"title": "TrackProductAnalyticsEventResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"Turn": {
|
||||
@@ -17370,6 +17387,13 @@
|
||||
"title": "TurnSteerResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"UsageLimitBannerAction": {
|
||||
"enum": [
|
||||
"shown",
|
||||
"cta_clicked"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"UsageLimitBannerType": {
|
||||
"enum": [
|
||||
"workspace_member_credits_depleted",
|
||||
|
||||
+46
-22
@@ -2288,13 +2288,13 @@
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"account/usageLimitBanner/track"
|
||||
"analytics/productEvent/track"
|
||||
],
|
||||
"title": "Account/usageLimitBanner/trackRequestMethod",
|
||||
"title": "Analytics/productEvent/trackRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/TrackUsageLimitBannerParams"
|
||||
"$ref": "#/definitions/TrackProductAnalyticsEventParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -2302,7 +2302,7 @@
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Account/usageLimitBanner/trackRequest",
|
||||
"title": "Analytics/productEvent/trackRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
@@ -8737,6 +8737,34 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ProductAnalyticsEvent": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"action": {
|
||||
"$ref": "#/definitions/UsageLimitBannerAction"
|
||||
},
|
||||
"bannerType": {
|
||||
"$ref": "#/definitions/UsageLimitBannerType"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"usageLimitBanner"
|
||||
],
|
||||
"title": "UsageLimitBannerProductAnalyticsEventType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action",
|
||||
"bannerType",
|
||||
"type"
|
||||
],
|
||||
"title": "UsageLimitBannerProductAnalyticsEvent",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ProfileV2": {
|
||||
"additionalProperties": true,
|
||||
"properties": {
|
||||
@@ -14803,33 +14831,22 @@
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"TrackUsageLimitBannerAction": {
|
||||
"enum": [
|
||||
"shown",
|
||||
"cta_clicked"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"TrackUsageLimitBannerParams": {
|
||||
"TrackProductAnalyticsEventParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"action": {
|
||||
"$ref": "#/definitions/TrackUsageLimitBannerAction"
|
||||
},
|
||||
"bannerType": {
|
||||
"$ref": "#/definitions/UsageLimitBannerType"
|
||||
"event": {
|
||||
"$ref": "#/definitions/ProductAnalyticsEvent"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action",
|
||||
"bannerType"
|
||||
"event"
|
||||
],
|
||||
"title": "TrackUsageLimitBannerParams",
|
||||
"title": "TrackProductAnalyticsEventParams",
|
||||
"type": "object"
|
||||
},
|
||||
"TrackUsageLimitBannerResponse": {
|
||||
"TrackProductAnalyticsEventResponse": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "TrackUsageLimitBannerResponse",
|
||||
"title": "TrackProductAnalyticsEventResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"Turn": {
|
||||
@@ -15256,6 +15273,13 @@
|
||||
"title": "TurnSteerResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"UsageLimitBannerAction": {
|
||||
"enum": [
|
||||
"shown",
|
||||
"cta_clicked"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"UsageLimitBannerType": {
|
||||
"enum": [
|
||||
"workspace_member_credits_depleted",
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"ProductAnalyticsEvent": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"action": {
|
||||
"$ref": "#/definitions/UsageLimitBannerAction"
|
||||
},
|
||||
"bannerType": {
|
||||
"$ref": "#/definitions/UsageLimitBannerType"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"usageLimitBanner"
|
||||
],
|
||||
"title": "UsageLimitBannerProductAnalyticsEventType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action",
|
||||
"bannerType",
|
||||
"type"
|
||||
],
|
||||
"title": "UsageLimitBannerProductAnalyticsEvent",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"UsageLimitBannerAction": {
|
||||
"enum": [
|
||||
"shown",
|
||||
"cta_clicked"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"UsageLimitBannerType": {
|
||||
"enum": [
|
||||
"workspace_member_credits_depleted",
|
||||
"workspace_member_usage_limit_reached"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"event": {
|
||||
"$ref": "#/definitions/ProductAnalyticsEvent"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"event"
|
||||
],
|
||||
"title": "TrackProductAnalyticsEventParams",
|
||||
"type": "object"
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "TrackUsageLimitBannerResponse",
|
||||
"title": "TrackProductAnalyticsEventResponse",
|
||||
"type": "object"
|
||||
}
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"TrackUsageLimitBannerAction": {
|
||||
"enum": [
|
||||
"shown",
|
||||
"cta_clicked"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"UsageLimitBannerType": {
|
||||
"enum": [
|
||||
"workspace_member_credits_depleted",
|
||||
"workspace_member_usage_limit_reached"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"action": {
|
||||
"$ref": "#/definitions/TrackUsageLimitBannerAction"
|
||||
},
|
||||
"bannerType": {
|
||||
"$ref": "#/definitions/UsageLimitBannerType"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action",
|
||||
"bannerType"
|
||||
],
|
||||
"title": "TrackUsageLimitBannerParams",
|
||||
"type": "object"
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
+2
-2
@@ -1,7 +1,7 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { TrackUsageLimitBannerAction } from "./TrackUsageLimitBannerAction";
|
||||
import type { UsageLimitBannerAction } from "./UsageLimitBannerAction";
|
||||
import type { UsageLimitBannerType } from "./UsageLimitBannerType";
|
||||
|
||||
export type TrackUsageLimitBannerParams = { action: TrackUsageLimitBannerAction, bannerType: UsageLimitBannerType, };
|
||||
export type ProductAnalyticsEvent = { "type": "usageLimitBanner", action: UsageLimitBannerAction, bannerType: UsageLimitBannerType, };
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { ProductAnalyticsEvent } from "./ProductAnalyticsEvent";
|
||||
|
||||
export type TrackProductAnalyticsEventParams = { event: ProductAnalyticsEvent, };
|
||||
+1
-1
@@ -2,4 +2,4 @@
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type TrackUsageLimitBannerAction = "shown" | "cta_clicked";
|
||||
export type TrackProductAnalyticsEventResponse = Record<string, never>;
|
||||
+1
-1
@@ -2,4 +2,4 @@
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type TrackUsageLimitBannerResponse = Record<string, never>;
|
||||
export type UsageLimitBannerAction = "shown" | "cta_clicked";
|
||||
+4
-3
@@ -271,6 +271,7 @@ export type { PluginSummary } from "./PluginSummary";
|
||||
export type { PluginUninstallParams } from "./PluginUninstallParams";
|
||||
export type { PluginUninstallResponse } from "./PluginUninstallResponse";
|
||||
export type { PluginsMigration } from "./PluginsMigration";
|
||||
export type { ProductAnalyticsEvent } from "./ProductAnalyticsEvent";
|
||||
export type { ProfileV2 } from "./ProfileV2";
|
||||
export type { RateLimitReachedType } from "./RateLimitReachedType";
|
||||
export type { RateLimitSnapshot } from "./RateLimitSnapshot";
|
||||
@@ -386,9 +387,8 @@ export type { ToolRequestUserInputParams } from "./ToolRequestUserInputParams";
|
||||
export type { ToolRequestUserInputQuestion } from "./ToolRequestUserInputQuestion";
|
||||
export type { ToolRequestUserInputResponse } from "./ToolRequestUserInputResponse";
|
||||
export type { ToolsV2 } from "./ToolsV2";
|
||||
export type { TrackUsageLimitBannerAction } from "./TrackUsageLimitBannerAction";
|
||||
export type { TrackUsageLimitBannerParams } from "./TrackUsageLimitBannerParams";
|
||||
export type { TrackUsageLimitBannerResponse } from "./TrackUsageLimitBannerResponse";
|
||||
export type { TrackProductAnalyticsEventParams } from "./TrackProductAnalyticsEventParams";
|
||||
export type { TrackProductAnalyticsEventResponse } from "./TrackProductAnalyticsEventResponse";
|
||||
export type { Turn } from "./Turn";
|
||||
export type { TurnCompletedNotification } from "./TurnCompletedNotification";
|
||||
export type { TurnDiffUpdatedNotification } from "./TurnDiffUpdatedNotification";
|
||||
@@ -405,6 +405,7 @@ export type { TurnStartedNotification } from "./TurnStartedNotification";
|
||||
export type { TurnStatus } from "./TurnStatus";
|
||||
export type { TurnSteerParams } from "./TurnSteerParams";
|
||||
export type { TurnSteerResponse } from "./TurnSteerResponse";
|
||||
export type { UsageLimitBannerAction } from "./UsageLimitBannerAction";
|
||||
export type { UsageLimitBannerType } from "./UsageLimitBannerType";
|
||||
export type { UserInput } from "./UserInput";
|
||||
export type { WarningNotification } from "./WarningNotification";
|
||||
|
||||
@@ -573,9 +573,9 @@ client_request_definitions! {
|
||||
response: v2::SendAddCreditsNudgeEmailResponse,
|
||||
},
|
||||
|
||||
TrackUsageLimitBanner => "account/usageLimitBanner/track" {
|
||||
params: v2::TrackUsageLimitBannerParams,
|
||||
response: v2::TrackUsageLimitBannerResponse,
|
||||
TrackProductAnalyticsEvent => "analytics/productEvent/track" {
|
||||
params: v2::TrackProductAnalyticsEventParams,
|
||||
response: v2::TrackProductAnalyticsEventResponse,
|
||||
},
|
||||
|
||||
FeedbackUpload => "feedback/upload" {
|
||||
@@ -1468,23 +1468,28 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_track_usage_limit_banner() -> Result<()> {
|
||||
let request = ClientRequest::TrackUsageLimitBanner {
|
||||
fn serialize_track_product_analytics_event() -> Result<()> {
|
||||
let request = ClientRequest::TrackProductAnalyticsEvent {
|
||||
request_id: RequestId::Integer(2),
|
||||
params: v2::TrackUsageLimitBannerParams {
|
||||
action: v2::TrackUsageLimitBannerAction::CtaClicked,
|
||||
banner_type: v2::UsageLimitBannerType::WorkspaceMemberUsageLimitReached,
|
||||
params: v2::TrackProductAnalyticsEventParams {
|
||||
event: v2::ProductAnalyticsEvent::UsageLimitBanner {
|
||||
action: v2::UsageLimitBannerAction::CtaClicked,
|
||||
banner_type: v2::UsageLimitBannerType::WorkspaceMemberUsageLimitReached,
|
||||
},
|
||||
},
|
||||
};
|
||||
assert_eq!(request.id(), &RequestId::Integer(2));
|
||||
assert_eq!(request.method(), "account/usageLimitBanner/track");
|
||||
assert_eq!(request.method(), "analytics/productEvent/track");
|
||||
assert_eq!(
|
||||
json!({
|
||||
"method": "account/usageLimitBanner/track",
|
||||
"method": "analytics/productEvent/track",
|
||||
"id": 2,
|
||||
"params": {
|
||||
"action": "cta_clicked",
|
||||
"bannerType": "workspace_member_usage_limit_reached",
|
||||
"event": {
|
||||
"type": "usageLimitBanner",
|
||||
"action": "cta_clicked",
|
||||
"bannerType": "workspace_member_usage_limit_reached",
|
||||
},
|
||||
},
|
||||
}),
|
||||
serde_json::to_value(&request)?,
|
||||
|
||||
@@ -2253,15 +2253,26 @@ pub struct SendAddCreditsNudgeEmailParams {
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct TrackUsageLimitBannerParams {
|
||||
pub action: TrackUsageLimitBannerAction,
|
||||
pub banner_type: UsageLimitBannerType,
|
||||
pub struct TrackProductAnalyticsEventParams {
|
||||
pub event: ProductAnalyticsEvent,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(tag = "type", rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/", tag = "type", rename_all = "camelCase")]
|
||||
pub enum ProductAnalyticsEvent {
|
||||
UsageLimitBanner {
|
||||
action: UsageLimitBannerAction,
|
||||
#[serde(rename = "bannerType")]
|
||||
#[ts(rename = "bannerType")]
|
||||
banner_type: UsageLimitBannerType,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(export_to = "v2/", rename_all = "snake_case")]
|
||||
pub enum TrackUsageLimitBannerAction {
|
||||
pub enum UsageLimitBannerAction {
|
||||
Shown,
|
||||
CtaClicked,
|
||||
}
|
||||
@@ -2292,7 +2303,7 @@ pub struct SendAddCreditsNudgeEmailResponse {
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct TrackUsageLimitBannerResponse {}
|
||||
pub struct TrackProductAnalyticsEventResponse {}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
|
||||
@@ -1559,7 +1559,6 @@ Codex supports these authentication modes. The current mode is surfaced in `acco
|
||||
- `account/rateLimits/read` — fetch ChatGPT rate limits; updates arrive via `account/rateLimits/updated` (notify).
|
||||
- `account/rateLimits/updated` (notify) — emitted whenever a user's ChatGPT rate limits change.
|
||||
- `account/sendAddCreditsNudgeEmail` — ask ChatGPT to email the workspace owner about depleted credits or a reached usage limit.
|
||||
- `account/usageLimitBanner/track` — record that the CLI workspace-owner nudge prompt was shown or its CTA was clicked.
|
||||
- `mcpServer/oauthLogin/completed` (notify) — emitted after a `mcpServer/oauth/login` flow finishes for a server; payload includes `{ name, success, error? }`.
|
||||
- `mcpServer/startupStatus/updated` (notify) — emitted when a configured MCP server's startup status changes for a loaded thread; payload includes `{ name, status, error }` where `status` is `starting`, `ready`, `failed`, or `cancelled`.
|
||||
|
||||
@@ -1672,14 +1671,18 @@ Field notes:
|
||||
|
||||
Use `creditType: "credits"` when workspace credits are depleted, or `creditType: "usage_limit"` when the workspace usage limit has been reached. If the owner was already notified recently, the response status is `cooldown_active`.
|
||||
|
||||
### 9) Track a usage-limit banner
|
||||
## Product analytics endpoints
|
||||
|
||||
- `analytics/productEvent/track` — record a typed client-side product analytics event.
|
||||
|
||||
### Track a product analytics event
|
||||
|
||||
```json
|
||||
{ "method": "account/usageLimitBanner/track", "id": 9, "params": { "action": "shown", "bannerType": "workspace_member_usage_limit_reached" } }
|
||||
{ "method": "analytics/productEvent/track", "id": 9, "params": { "event": { "type": "usageLimitBanner", "action": "shown", "bannerType": "workspace_member_usage_limit_reached" } } }
|
||||
{ "id": 9, "result": {} }
|
||||
```
|
||||
|
||||
Use `action: "shown"` when the banner is displayed, and `action: "cta_clicked"` when the user confirms it. The current workspace-owner nudge variants are `workspace_member_credits_depleted` and `workspace_member_usage_limit_reached`.
|
||||
The current `usageLimitBanner` product event records when the CLI workspace-owner nudge prompt is shown or its CTA is clicked. Use `action: "shown"` when the banner is displayed, and `action: "cta_clicked"` when the user confirms it. The current workspace-owner nudge variants are `workspace_member_credits_depleted` and `workspace_member_usage_limit_reached`.
|
||||
|
||||
## Experimental API Opt-in
|
||||
|
||||
|
||||
@@ -211,7 +211,7 @@ use codex_app_server_protocol::ThreadUnarchivedNotification;
|
||||
use codex_app_server_protocol::ThreadUnsubscribeParams;
|
||||
use codex_app_server_protocol::ThreadUnsubscribeResponse;
|
||||
use codex_app_server_protocol::ThreadUnsubscribeStatus;
|
||||
use codex_app_server_protocol::TrackUsageLimitBannerResponse;
|
||||
use codex_app_server_protocol::TrackProductAnalyticsEventResponse;
|
||||
use codex_app_server_protocol::Turn;
|
||||
use codex_app_server_protocol::TurnError;
|
||||
use codex_app_server_protocol::TurnInterruptParams;
|
||||
@@ -1275,14 +1275,14 @@ impl CodexMessageProcessor {
|
||||
self.send_add_credits_nudge_email(to_connection_request_id(request_id), params)
|
||||
.await;
|
||||
}
|
||||
ClientRequest::TrackUsageLimitBanner {
|
||||
ClientRequest::TrackProductAnalyticsEvent {
|
||||
request_id,
|
||||
params: _,
|
||||
} => {
|
||||
self.outgoing
|
||||
.send_response(
|
||||
to_connection_request_id(request_id),
|
||||
TrackUsageLimitBannerResponse {},
|
||||
TrackProductAnalyticsEventResponse {},
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
@@ -716,7 +716,7 @@ impl MessageProcessor {
|
||||
let connection_id = connection_request_id.connection_id;
|
||||
if let ClientRequest::TurnStart { request_id, .. }
|
||||
| ClientRequest::TurnSteer { request_id, .. }
|
||||
| ClientRequest::TrackUsageLimitBanner { request_id, .. } = &codex_request
|
||||
| ClientRequest::TrackProductAnalyticsEvent { request_id, .. } = &codex_request
|
||||
{
|
||||
self.analytics_events_client.track_request(
|
||||
connection_id.0,
|
||||
|
||||
Reference in New Issue
Block a user