mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Billing for formula assistant
Summary: Adding limits for AI calls and connecting those limits with a Stripe Account. - New table in homedb called `limits` - All calls to the AI are not routed through DocApi and measured. - All products now contain a special key `assistantLimit`, with a default value 0 - Limit is reset every time the subscription has changed its period - The billing page is updated with two new options that describe the AI plan - There is a new popup that allows the user to upgrade to a higher plan - Tiers are read directly from the Stripe product with a volume pricing model Test Plan: Updated and added Reviewers: georgegevoian, paulfitz Reviewed By: georgegevoian Subscribers: dsagal Differential Revision: https://phab.getgrist.com/D3907
This commit is contained in:
@@ -25,7 +25,7 @@
|
||||
|
||||
|
||||
import { ActiveDoc, Deps as ActiveDocDeps } from "app/server/lib/ActiveDoc";
|
||||
import { DEPS } from "app/server/lib/Assistance";
|
||||
import { DEPS, sendForCompletion } from "app/server/lib/Assistance";
|
||||
import log from 'app/server/lib/log';
|
||||
import crypto from 'crypto';
|
||||
import parse from 'csv-parse/lib/sync';
|
||||
@@ -163,7 +163,7 @@ where c.colId = ? and t.tableId = ?
|
||||
`, rec.col_id, rec.table_id);
|
||||
formula = colInfo?.formula;
|
||||
|
||||
const result = await activeDoc.getAssistanceWithOptions(session, {
|
||||
const result = await sendForCompletion(session, activeDoc, {
|
||||
context: {type: 'formula', tableId, colId},
|
||||
state: history,
|
||||
text: followUp || description,
|
||||
|
||||
@@ -558,7 +558,7 @@ describe('DocTutorial', function () {
|
||||
|
||||
// Check that the update is immediately reflected in the tutorial popup.
|
||||
assert.equal(
|
||||
await driver.find('.test-doc-tutorial-popup p').getText(),
|
||||
await driver.findWait('.test-doc-tutorial-popup p', 2000).getText(),
|
||||
'Welcome to the Grist Basics tutorial V2.'
|
||||
);
|
||||
|
||||
@@ -571,7 +571,7 @@ describe('DocTutorial', function () {
|
||||
// Switch to another user and restart the tutorial.
|
||||
viewerSession = await gu.session().teamSite.user('user2').login();
|
||||
await viewerSession.loadDoc(`/doc/${doc.id}`);
|
||||
await driver.find('.test-doc-tutorial-popup-restart').click();
|
||||
await driver.findWait('.test-doc-tutorial-popup-restart', 2000).click();
|
||||
await driver.find('.test-modal-confirm').click();
|
||||
await gu.waitForServer();
|
||||
await driver.findWait('.test-doc-tutorial-popup', 2000);
|
||||
|
||||
@@ -2056,7 +2056,13 @@ export class Session {
|
||||
isFirstLogin?: boolean,
|
||||
showTips?: boolean,
|
||||
skipTutorial?: boolean, // By default true
|
||||
userName?: string,
|
||||
email?: string,
|
||||
retainExistingLogin?: boolean}) {
|
||||
if (options?.userName) {
|
||||
this.settings.name = options.userName;
|
||||
this.settings.email = options.email || '';
|
||||
}
|
||||
// Optimize testing a little bit, so if we are already logged in as the expected
|
||||
// user on the expected org, and there are no options set, we can just continue.
|
||||
if (!options && await this.isLoggedInCorrectly()) { return this; }
|
||||
@@ -3150,20 +3156,26 @@ export async function availableBehaviorOptions() {
|
||||
return list;
|
||||
}
|
||||
|
||||
export function withComments() {
|
||||
let oldEnv: testUtils.EnvironmentSnapshot;
|
||||
/**
|
||||
* Restarts the server ensuring that it is run with the given environment variables.
|
||||
* If variables are already set, the server is not restarted.
|
||||
*
|
||||
* Useful for local testing of features that depend on environment variables, as it avoids the need
|
||||
* to restart the server when those variables are already set.
|
||||
*/
|
||||
export function withEnvironmentSnapshot(vars: Record<string, any>) {
|
||||
let oldEnv: testUtils.EnvironmentSnapshot|null = null;
|
||||
before(async () => {
|
||||
if (process.env.COMMENTS !== 'true') {
|
||||
oldEnv = new testUtils.EnvironmentSnapshot();
|
||||
process.env.COMMENTS = 'true';
|
||||
await server.restart();
|
||||
}
|
||||
// Test if the vars are already set, and if so, skip.
|
||||
if (Object.keys(vars).every(k => process.env[k] === vars[k])) { return; }
|
||||
oldEnv = new testUtils.EnvironmentSnapshot();
|
||||
Object.assign(process.env, vars);
|
||||
await server.restart();
|
||||
});
|
||||
after(async () => {
|
||||
if (oldEnv) {
|
||||
oldEnv.restore();
|
||||
await server.restart();
|
||||
}
|
||||
if (!oldEnv) { return; }
|
||||
oldEnv.restore();
|
||||
await server.restart();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user