Skip to content
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

feat(backend): Add graph/node id & execution id on CreditTransaction table #9217

Open
wants to merge 68 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
96f850d
Add `useCredits` hook
kcze Dec 11, 2024
d915b80
Top-up section in user profile
kcze Dec 12, 2024
0f917f7
Request top-up endpoint
kcze Dec 12, 2024
2481d3d
Merge branch 'dev' into kpczerwinski/secrt-1012-mvp-implement-top-up-…
kcze Dec 12, 2024
1596671
Top-Up intent logic
kcze Dec 13, 2024
43d0752
Merge branch 'dev' into kpczerwinski/secrt-1012-mvp-implement-top-up-…
kcze Dec 18, 2024
afdb6e2
Install `stripe-js`
kcze Dec 19, 2024
e8fa2a1
Use stripe checkout
kcze Dec 19, 2024
869c31c
Update top up endpoint
kcze Dec 25, 2024
9cddffb
Fulfill checkout function
kcze Dec 27, 2024
76b5259
Handle Stripe webhook events
kcze Dec 28, 2024
b3d7804
Update `credit.py`
kcze Dec 31, 2024
7063751
Fix top-up credit amounts
kcze Dec 31, 2024
27019e4
Move top-up UI to `/store/credits`
kcze Jan 1, 2025
b3de888
Hide Credits tab conditionally
kcze Jan 1, 2025
bb69c5a
Success and cancel topup message
kcze Jan 1, 2025
2caf498
Address feedback
kcze Jan 1, 2025
f25c722
feat(backend): Add running balance and introduce atomicity on transac…
majdyz Jan 3, 2025
deddcdd
Client-side `/credits` PATCH
kcze Jan 3, 2025
c6eaa58
Merge branch 'dev' into kpczerwinski/secrt-1012-mvp-implement-top-up-…
kcze Jan 3, 2025
7958143
Cleanup
kcze Jan 3, 2025
69c2132
Merge branch 'dev' into zamilmajdy/secrt-1014-scalability-implement-t…
majdyz Jan 3, 2025
07ebac3
Add postgres lock
majdyz Jan 3, 2025
a1c4a02
Merge remote-tracking branch 'origin/zamilmajdy/secrt-1014-scalabilit…
majdyz Jan 3, 2025
4cd2f60
Update `poetry.lock`
kcze Jan 5, 2025
8de9450
Use app-level createdAt time
majdyz Jan 6, 2025
1583fda
Merge branch 'dev' into kpczerwinski/secrt-1012-mvp-implement-top-up-…
majdyz Jan 6, 2025
acaa10e
Rebase PR
majdyz Jan 7, 2025
72bcc42
Reduce change
majdyz Jan 7, 2025
5121724
Fix test
majdyz Jan 7, 2025
7e76c63
Remove get_balance
majdyz Jan 7, 2025
98ac77f
Cosmetic
majdyz Jan 7, 2025
ceaa1bf
Fix credit
majdyz Jan 7, 2025
38b662b
Merge branch 'dev' into kpczerwinski/secrt-1012-mvp-implement-top-up-…
kcze Jan 7, 2025
0c579fd
Add missing line to `poetry.lock`
kcze Jan 7, 2025
5ec40c2
Fix refill value
kcze Jan 7, 2025
f28b298
Address feedback
kcze Jan 7, 2025
4d269d1
Merge branch 'dev' of github.com:Significant-Gravitas/AutoGPT into za…
majdyz Jan 7, 2025
052d019
Merge branch 'kpczerwinski/secrt-1012-mvp-implement-top-up-flow' of g…
majdyz Jan 7, 2025
413b5b8
Merge branch 'dev' of github.com:Significant-Gravitas/AutoGPT into za…
majdyz Jan 8, 2025
31ff0e9
Fix credit
majdyz Jan 8, 2025
f12e8c4
feat(backend): Add graph/node id & execution id on CreditTransaction …
majdyz Jan 8, 2025
496fd75
feat(backend): Add graph/node id & execution id on CreditTransaction …
majdyz Jan 8, 2025
96db700
Drop index
majdyz Jan 8, 2025
c7e994c
Merge branch 'dev' of github.com:Significant-Gravitas/AutoGPT into kp…
majdyz Jan 11, 2025
9c2bc4b
Set default value for `PLATFORM_BASE_URL`
majdyz Jan 11, 2025
427da2f
Set default value for `PLATFORM_BASE_URL`
majdyz Jan 11, 2025
86406cd
Revert unused change
majdyz Jan 11, 2025
5af0648
feat(backend): Add running balance and introduce atomicity on transac…
majdyz Jan 13, 2025
9a96d93
Update autogpt_platform/backend/migrations/20250108003202_reshape_tra…
majdyz Jan 13, 2025
f7c4d3b
Merge branch 'dev' of github.com:Significant-Gravitas/AutoGPT into za…
majdyz Jan 13, 2025
6751812
Merge branch 'kpczerwinski/secrt-1012-mvp-implement-top-up-flow' of g…
majdyz Jan 13, 2025
2bfb3cc
Merge branch 'zamilmajdy/secrt-1015-phase-2-add-agentnodeexecution-id…
majdyz Jan 13, 2025
46eb6c8
Merge branch 'dev' of github.com:Significant-Gravitas/AutoGPT into kp…
majdyz Jan 13, 2025
d1dce4b
Merge branch 'kpczerwinski/secrt-1012-mvp-implement-top-up-flow' of g…
majdyz Jan 13, 2025
d48e91a
Merge branch 'kpczerwinski/secrt-1012-mvp-implement-top-up-flow' of g…
majdyz Jan 13, 2025
eba97ad
Remove useless indexes
majdyz Jan 13, 2025
16d9150
Remove useless indexes
majdyz Jan 13, 2025
a5b6393
Refresh migraiton time
majdyz Jan 13, 2025
d8ee532
Merge branch 'kpczerwinski/secrt-1012-mvp-implement-top-up-flow' of g…
majdyz Jan 13, 2025
9e27039
Merge branch 'dev' into kpczerwinski/secrt-1012-mvp-implement-top-up-…
majdyz Jan 13, 2025
0518b36
Merge remote-tracking branch 'origin/kpczerwinski/secrt-1012-mvp-impl…
Pwuts Jan 14, 2025
12d0dd8
Merge branch 'dev' into kpczerwinski/secrt-1012-mvp-implement-top-up-…
majdyz Jan 15, 2025
fb1f0f5
refresh migration date
majdyz Jan 15, 2025
75e3fbb
Merge branch 'kpczerwinski/secrt-1012-mvp-implement-top-up-flow' of g…
majdyz Jan 15, 2025
1d3f111
refresh migration date
majdyz Jan 15, 2025
b50dbbd
Merge branch 'dev' of github.com:Significant-Gravitas/AutoGPT into za…
majdyz Jan 16, 2025
fd0b39c
Update latest migration state
majdyz Jan 16, 2025
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
29 changes: 13 additions & 16 deletions autogpt_platform/backend/backend/data/credit.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from backend.data.block import Block, BlockInput, get_block
from backend.data.block_cost_config import BLOCK_COSTS
from backend.data.cost import BlockCost, BlockCostType
from backend.data.execution import NodeExecutionEntry
from backend.data.user import get_user_by_id
from backend.util.settings import Settings

Expand All @@ -33,19 +34,15 @@ async def get_credits(self, user_id: str) -> int:
@abstractmethod
async def spend_credits(
self,
user_id: str,
block_id: str,
input_data: BlockInput,
entry: NodeExecutionEntry,
data_size: float,
run_time: float,
) -> int:
"""
Spend the credits for the user based on the block usage.

Args:
user_id (str): The user ID.
block_id (str): The block ID.
input_data (BlockInput): The input data for the block.
entry (NodeExecutionEntry): The node execution identifiers & data.
data_size (float): The size of the data being processed.
run_time (float): The time taken to run the block.

Expand Down Expand Up @@ -168,7 +165,6 @@ async def _add_transaction(
transaction_type: CreditTransactionType,
is_active: bool = True,
transaction_key: str | None = None,
block_id: str | None = None,
metadata: Json = Json({}),
):
async with db.locked_transaction(f"usr_trx_{user_id}"):
Expand All @@ -185,7 +181,6 @@ async def _add_transaction(
"amount": amount,
"runningBalance": user_balance + amount,
"type": transaction_type,
"blockId": block_id,
"metadata": metadata,
"isActive": is_active,
"createdAt": self.time_now(),
Expand Down Expand Up @@ -251,29 +246,31 @@ def _is_cost_filter_match(

async def spend_credits(
self,
user_id: str,
block_id: str,
input_data: BlockInput,
entry: NodeExecutionEntry,
data_size: float,
run_time: float,
) -> int:
block = get_block(block_id)
block = get_block(entry.block_id)
if not block:
raise ValueError(f"Block not found: {block_id}")
raise ValueError(f"Block not found: {entry.block_id}")

cost, matching_filter = self._block_usage_cost(
block=block, input_data=input_data, data_size=data_size, run_time=run_time
block=block, input_data=entry.data, data_size=data_size, run_time=run_time
)
if cost == 0:
return 0

await self._add_transaction(
user_id=user_id,
user_id=entry.user_id,
amount=-cost,
transaction_type=CreditTransactionType.USAGE,
block_id=block.id,
metadata=Json(
{
"graph_exec_id": entry.graph_exec_id,
"graph_id": entry.graph_id,
"node_id": entry.node_id,
"node_exec_id": entry.node_exec_id,
"block_id": entry.block_id,
"block": block.name,
"input": matching_filter,
}
Expand Down
1 change: 1 addition & 0 deletions autogpt_platform/backend/backend/data/execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class NodeExecutionEntry(BaseModel):
graph_id: str
node_exec_id: str
node_id: str
block_id: str
data: BlockInput


Expand Down
3 changes: 2 additions & 1 deletion autogpt_platform/backend/backend/executor/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from backend.data.credit import get_user_credit_model
from backend.data.execution import (
ExecutionResult,
NodeExecutionEntry,
RedisExecutionEventBus,
create_graph_execution,
get_execution_results,
Expand Down Expand Up @@ -79,7 +80,7 @@ def wrapper(self, *args: P.args, **kwargs: P.kwargs) -> R:
# Credits
user_credit_model = get_user_credit_model()
spend_credits = cast(
Callable[[Any, str, str, dict[str, str], float, float], int],
Callable[[Any, NodeExecutionEntry, float, float], int],
exposed_run_and_wait(user_credit_model.spend_credits),
)

Expand Down
21 changes: 17 additions & 4 deletions autogpt_platform/backend/backend/executor/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,8 @@ def update_execution(status: ExecutionStatus) -> ExecutionResult:
if res.end_time and res.start_time
else 0
)
db_client.spend_credits(user_id, node_block.id, input_data, s, t)
data.data = input_data
db_client.spend_credits(data, s, t)

# Update execution stats
if execution_stats is not None:
Expand All @@ -257,7 +258,7 @@ def _enqueue_next_nodes(
log_metadata: LogMetadata,
) -> list[NodeExecutionEntry]:
def add_enqueued_execution(
node_exec_id: str, node_id: str, data: BlockInput
node_exec_id: str, node_id: str, block_id: str, data: BlockInput
) -> NodeExecutionEntry:
exec_update = db_client.update_execution_status(
node_exec_id, ExecutionStatus.QUEUED, data
Expand All @@ -269,6 +270,7 @@ def add_enqueued_execution(
graph_id=graph_id,
node_exec_id=node_exec_id,
node_id=node_id,
block_id=block_id,
data=data,
)

Expand Down Expand Up @@ -322,7 +324,12 @@ def register_next_executions(node_link: Link) -> list[NodeExecutionEntry]:
# Input is complete, enqueue the execution.
log_metadata.info(f"Enqueued {suffix}")
enqueued_executions.append(
add_enqueued_execution(next_node_exec_id, next_node_id, next_node_input)
add_enqueued_execution(
node_exec_id=next_node_exec_id,
node_id=next_node_id,
block_id=next_node.block_id,
data=next_node_input,
)
)

# Next execution stops here if the link is not static.
Expand Down Expand Up @@ -352,7 +359,12 @@ def register_next_executions(node_link: Link) -> list[NodeExecutionEntry]:
continue
log_metadata.info(f"Enqueueing static-link execution {suffix}")
enqueued_executions.append(
add_enqueued_execution(iexec.node_exec_id, next_node_id, idata)
add_enqueued_execution(
node_exec_id=iexec.node_exec_id,
node_id=next_node_id,
block_id=next_node.block_id,
data=idata,
)
)
return enqueued_executions

Expand Down Expand Up @@ -837,6 +849,7 @@ def add_execution(
graph_id=node_exec.graph_id,
node_exec_id=node_exec.node_exec_id,
node_id=node_exec.node_id,
block_id=node_exec.block_id,
data=node_exec.input_data,
)
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
Warnings:

- You are about to drop the column `blockId` on the `CreditTransaction` table. All the data in the column will be moved to metadata->block_id.

*/
BEGIN;

-- DropForeignKey blockId
ALTER TABLE "CreditTransaction" DROP CONSTRAINT "CreditTransaction_blockId_fkey";

-- Update migrate blockId into metadata->"block_id"
UPDATE "CreditTransaction"
SET "metadata" = jsonb_set(
COALESCE("metadata"::jsonb, '{}'),
'{block_id}',
to_jsonb("blockId")
)
WHERE "blockId" IS NOT NULL;

-- AlterTable drop blockId
ALTER TABLE "CreditTransaction" DROP COLUMN "blockId";

COMMIT;

/*
These indices dropped below were part of the cleanup during the schema change applied above.
These indexes were not useful and will not impact anything upon their removal.
*/

-- DropIndex
DROP INDEX "StoreListingReview_storeListingVersionId_idx";

-- DropIndex
DROP INDEX "StoreListingSubmission_Status_idx";
78 changes: 36 additions & 42 deletions autogpt_platform/backend/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ model User {
AgentPreset AgentPreset[]
UserAgent UserAgent[]

Profile Profile[]
StoreListing StoreListing[]
StoreListingReview StoreListingReview[]
StoreListingSubmission StoreListingSubmission[]
APIKeys APIKey[]
IntegrationWebhooks IntegrationWebhook[]
Profile Profile[]
StoreListing StoreListing[]
StoreListingReview StoreListingReview[]
StoreListingSubmission StoreListingSubmission[]
APIKeys APIKey[]
IntegrationWebhooks IntegrationWebhook[]

@@index([id])
@@index([email])
Expand All @@ -64,23 +64,23 @@ model AgentGraph {
AgentNodes AgentNode[]
AgentGraphExecution AgentGraphExecution[]

AgentPreset AgentPreset[]
UserAgent UserAgent[]
StoreListing StoreListing[]
StoreListingVersion StoreListingVersion?
AgentPreset AgentPreset[]
UserAgent UserAgent[]
StoreListing StoreListing[]
StoreListingVersion StoreListingVersion?

@@id(name: "graphVersionId", [id, version])
@@index([userId, isActive])
}

////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
//////////////// USER SPECIFIC DATA ////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////

// An AgentPrest is an Agent + User Configuration of that agent.
// For example, if someone has created a weather agent and they want to set it up to
// For example, if someone has created a weather agent and they want to set it up to
// Inform them of extreme weather warnings in Texas, the agent with the configuration to set it to
// monitor texas, along with the cron setup or webhook tiggers, is an AgentPreset
model AgentPreset {
Expand All @@ -102,9 +102,9 @@ model AgentPreset {
agentVersion Int
Agent AgentGraph @relation(fields: [agentId, agentVersion], references: [id, version], onDelete: Cascade)

InputPresets AgentNodeExecutionInputOutput[] @relation("AgentPresetsInputData")
UserAgents UserAgent[]
AgentExecution AgentGraphExecution[]
InputPresets AgentNodeExecutionInputOutput[] @relation("AgentPresetsInputData")
UserAgents UserAgent[]
AgentExecution AgentGraphExecution[]

@@index([userId])
}
Expand Down Expand Up @@ -134,11 +134,11 @@ model UserAgent {
@@index([userId])
}

////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
//////// AGENT DEFINITION AND EXECUTION TABLES ////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////

// This model describes a single node in the Agent Graph/Flow (Multi Agent System).
model AgentNode {
Expand Down Expand Up @@ -207,7 +207,6 @@ model AgentBlock {

// Prisma requires explicit back-references.
ReferencedByAgentNode AgentNode[]
CreditTransaction CreditTransaction[]
}

// This model describes the status of an AgentGraphExecution or AgentNodeExecution.
Expand Down Expand Up @@ -345,11 +344,11 @@ model AnalyticsDetails {
@@index([type])
}

////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////// METRICS TRACKING TABLES ////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
model AnalyticsMetrics {
id String @id @default(uuid())
createdAt DateTime @default(now())
Expand All @@ -375,21 +374,18 @@ enum CreditTransactionType {
USAGE
}

////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
//////// ACCOUNTING AND CREDIT SYSTEM TABLES //////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
model CreditTransaction {
transactionKey String @default(uuid())
createdAt DateTime @default(now())

userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)

blockId String?
block AgentBlock? @relation(fields: [blockId], references: [id])

amount Int
type CreditTransactionType

Expand All @@ -402,19 +398,19 @@ model CreditTransaction {
@@index([userId, createdAt])
}

////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////// Store TABLES ///////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////

model Profile {
id String @id @default(uuid())
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt

// Only 1 of user or group can be set.
// The user this profile belongs to, if any.
// The user this profile belongs to, if any.
userId String?
User User? @relation(fields: [userId], references: [id], onDelete: Cascade)

Expand Down Expand Up @@ -528,7 +524,7 @@ model StoreListingVersion {
agentVersion Int
Agent AgentGraph @relation(fields: [agentId, agentVersion], references: [id, version])

// The detials for this version of the agent, this allows the author to update the details of the agent,
// The details for this version of the agent, this allows the author to update the details of the agent,
// But still allow using old versions of the agent with there original details.
// TODO: Create a database view that shows only the latest version of each store listing.
slug String
Expand Down Expand Up @@ -573,7 +569,6 @@ model StoreListingReview {
comments String?

@@unique([storeListingVersionId, reviewByUserId])
@@index([storeListingVersionId])
}

enum SubmissionStatus {
Expand Down Expand Up @@ -601,7 +596,6 @@ model StoreListingSubmission {
reviewComments String?

@@index([storeListingId])
@@index([Status])
}

enum APIKeyPermission {
Expand Down
Loading
Loading