@fulcrum_io/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,410 @@
1
+ syntax = "proto3";
2
+
3
+ package fulcrum.cost.v1;
4
+
5
+ option go_package = "github.com/fulcrum-io/fulcrum/pkg/cost/v1";
6
+
7
+ import "google/api/annotations.proto";
8
+ import "google/protobuf/timestamp.proto";
9
+ import "fulcrum/envelope/v1/envelope.proto";
10
+
11
+ // CostService provides budget management and cost tracking capabilities.
12
+ // Supports creating budgets, tracking spend, and generating cost reports.
13
+ service CostService {
14
+ // Budget CRUD operations
15
+ rpc CreateBudget(CreateBudgetRequest) returns (CreateBudgetResponse) {
16
+ option (google.api.http) = {
17
+ post: "/v1/budgets"
18
+ body: "budget"
19
+ };
20
+ }
21
+
22
+ rpc GetBudget(GetBudgetRequest) returns (GetBudgetResponse) {
23
+ option (google.api.http) = {
24
+ get: "/v1/budgets/{budget_id}"
25
+ };
26
+ }
27
+
28
+ rpc UpdateBudget(UpdateBudgetRequest) returns (UpdateBudgetResponse) {
29
+ option (google.api.http) = {
30
+ patch: "/v1/budgets/{budget.budget_id}"
31
+ body: "budget"
32
+ };
33
+ }
34
+
35
+ rpc DeleteBudget(DeleteBudgetRequest) returns (DeleteBudgetResponse) {
36
+ option (google.api.http) = {
37
+ delete: "/v1/budgets/{budget_id}"
38
+ };
39
+ }
40
+
41
+ rpc ListBudgets(ListBudgetsRequest) returns (ListBudgetsResponse) {
42
+ option (google.api.http) = {
43
+ get: "/v1/budgets"
44
+ };
45
+ }
46
+
47
+ // Cost tracking and reporting
48
+ rpc GetCostSummary(GetCostSummaryRequest) returns (GetCostSummaryResponse) {
49
+ option (google.api.http) = {
50
+ get: "/v1/costs/{envelope_id}"
51
+ };
52
+ }
53
+
54
+ rpc GetSpendSummary(GetSpendSummaryRequest) returns (GetSpendSummaryResponse) {
55
+ option (google.api.http) = {
56
+ get: "/v1/spend"
57
+ };
58
+ }
59
+
60
+ rpc GetBudgetStatus(GetBudgetStatusRequest) returns (GetBudgetStatusResponse) {
61
+ option (google.api.http) = {
62
+ get: "/v1/budgets/{budget_id}/status"
63
+ };
64
+ }
65
+
66
+ // Cost prediction
67
+ rpc PredictCost(PredictCostRequest) returns (PredictCostResponse) {
68
+ option (google.api.http) = {
69
+ post: "/v1/costs/predict"
70
+ body: "*"
71
+ };
72
+ }
73
+ }
74
+
75
+ // Budget defines spend limits and notification thresholds for a tenant or workflow.
76
+ message Budget {
77
+ // Unique budget identifier
78
+ string budget_id = 1;
79
+
80
+ // Tenant or workflow this budget applies to
81
+ string tenant_id = 2;
82
+ string workflow_id = 3; // Optional: budget per workflow
83
+
84
+ // Budget limits
85
+ BudgetLimits limits = 4;
86
+
87
+ // Notification thresholds (percentage of limit)
88
+ repeated NotificationThreshold thresholds = 5;
89
+
90
+ // Budget period
91
+ BudgetPeriod period = 6;
92
+
93
+ // Current spend against this budget
94
+ SpendSummary current_spend = 7;
95
+
96
+ // Budget status
97
+ BudgetStatusType status = 8;
98
+
99
+ // Metadata
100
+ string name = 9;
101
+ string description = 10;
102
+ map<string, string> tags = 11;
103
+
104
+ // Timestamps
105
+ google.protobuf.Timestamp created_at = 12;
106
+ google.protobuf.Timestamp updated_at = 13;
107
+ google.protobuf.Timestamp reset_at = 14; // Last budget period reset
108
+ }
109
+
110
+ // BudgetLimits defines maximum allowed spend
111
+ message BudgetLimits {
112
+ // Token limits
113
+ int64 max_tokens = 1; // Total tokens (input + output)
114
+ int64 max_input_tokens = 2; // Input tokens only
115
+ int64 max_output_tokens = 3; // Output tokens only
116
+
117
+ // Cost limits
118
+ double max_cost_usd = 4; // Total cost in USD
119
+
120
+ // Call limits
121
+ int32 max_llm_calls = 5;
122
+ int32 max_tool_calls = 6;
123
+
124
+ // Time limits
125
+ int64 max_execution_time_seconds = 7;
126
+ }
127
+
128
+ // NotificationThreshold defines when to emit budget warnings
129
+ message NotificationThreshold {
130
+ // Percentage of budget consumed (0-100)
131
+ float threshold_percent = 1;
132
+
133
+ // Whether notification has been sent for current period
134
+ bool notified = 2;
135
+
136
+ // Last notification time
137
+ google.protobuf.Timestamp notified_at = 3;
138
+ }
139
+
140
+ // BudgetPeriod defines the budget reset cycle
141
+ message BudgetPeriod {
142
+ BudgetPeriodType period_type = 1;
143
+
144
+ // Custom period duration (for CUSTOM type)
145
+ int64 duration_seconds = 2;
146
+
147
+ // Period start/end (for fixed periods)
148
+ google.protobuf.Timestamp period_start = 3;
149
+ google.protobuf.Timestamp period_end = 4;
150
+ }
151
+
152
+ // BudgetPeriodType defines how often budgets reset
153
+ enum BudgetPeriodType {
154
+ BUDGET_PERIOD_TYPE_UNSPECIFIED = 0;
155
+ BUDGET_PERIOD_TYPE_HOURLY = 1;
156
+ BUDGET_PERIOD_TYPE_DAILY = 2;
157
+ BUDGET_PERIOD_TYPE_WEEKLY = 3;
158
+ BUDGET_PERIOD_TYPE_MONTHLY = 4;
159
+ BUDGET_PERIOD_TYPE_QUARTERLY = 5;
160
+ BUDGET_PERIOD_TYPE_YEARLY = 6;
161
+ BUDGET_PERIOD_TYPE_CUSTOM = 7; // Use duration_seconds
162
+ BUDGET_PERIOD_TYPE_INFINITE = 8; // Never resets
163
+ }
164
+
165
+ // SpendSummary aggregates spend information for a budget or tenant
166
+ message SpendSummary {
167
+ // Total tokens consumed
168
+ int64 total_tokens = 1;
169
+ int64 total_input_tokens = 2;
170
+ int64 total_output_tokens = 3;
171
+
172
+ // Total cost
173
+ double total_cost_usd = 4;
174
+
175
+ // Call counts
176
+ int32 total_llm_calls = 5;
177
+ int32 total_tool_calls = 6;
178
+
179
+ // Execution counts
180
+ int32 total_executions = 7;
181
+ int32 completed_executions = 8;
182
+ int32 failed_executions = 9;
183
+ int32 terminated_executions = 10;
184
+
185
+ // Time metrics
186
+ int64 total_execution_time_seconds = 11;
187
+ int64 average_execution_time_seconds = 12;
188
+
189
+ // Per-model breakdown
190
+ repeated fulcrum.envelope.v1.ModelCost model_costs = 13;
191
+
192
+ // Time period this summary covers
193
+ google.protobuf.Timestamp period_start = 14;
194
+ google.protobuf.Timestamp period_end = 15;
195
+ }
196
+
197
+ // BudgetStatus represents current budget consumption state
198
+ message BudgetStatus {
199
+ // Budget identifier
200
+ string budget_id = 1;
201
+
202
+ // Current status
203
+ BudgetStatusType status = 2;
204
+
205
+ // Usage percentages (0-100)
206
+ float token_usage_percent = 3;
207
+ float cost_usage_percent = 4;
208
+ float llm_call_usage_percent = 5;
209
+ float tool_call_usage_percent = 6;
210
+
211
+ // Remaining budget
212
+ BudgetLimits remaining = 7;
213
+
214
+ // Current spend
215
+ SpendSummary current_spend = 8;
216
+
217
+ // Next threshold
218
+ NotificationThreshold next_threshold = 9;
219
+
220
+ // Last updated
221
+ google.protobuf.Timestamp updated_at = 10;
222
+ }
223
+
224
+ // BudgetStatusType indicates budget health
225
+ enum BudgetStatusType {
226
+ BUDGET_STATUS_TYPE_UNSPECIFIED = 0;
227
+ BUDGET_STATUS_TYPE_OK = 1; // Under threshold
228
+ BUDGET_STATUS_TYPE_WARNING = 2; // Threshold reached (e.g., 80%)
229
+ BUDGET_STATUS_TYPE_CRITICAL = 3; // Near limit (e.g., 95%)
230
+ BUDGET_STATUS_TYPE_EXCEEDED = 4; // Limit reached, enforcement triggered
231
+ BUDGET_STATUS_TYPE_SUSPENDED = 5; // Budget manually suspended
232
+ }
233
+
234
+ // CreateBudgetRequest creates a new budget
235
+ message CreateBudgetRequest {
236
+ Budget budget = 1;
237
+ }
238
+
239
+ message CreateBudgetResponse {
240
+ Budget budget = 1;
241
+ }
242
+
243
+ // GetBudgetRequest retrieves a budget by ID
244
+ message GetBudgetRequest {
245
+ string budget_id = 1;
246
+ }
247
+
248
+ message GetBudgetResponse {
249
+ Budget budget = 1;
250
+ }
251
+
252
+ // UpdateBudgetRequest modifies an existing budget
253
+ message UpdateBudgetRequest {
254
+ Budget budget = 1;
255
+
256
+ // Field mask for partial updates
257
+ repeated string update_mask = 2;
258
+ }
259
+
260
+ message UpdateBudgetResponse {
261
+ Budget budget = 1;
262
+ }
263
+
264
+ // DeleteBudgetRequest removes a budget
265
+ message DeleteBudgetRequest {
266
+ string budget_id = 1;
267
+ }
268
+
269
+ message DeleteBudgetResponse {
270
+ bool success = 1;
271
+ }
272
+
273
+ // ListBudgetsRequest retrieves budgets with filtering
274
+ message ListBudgetsRequest {
275
+ // Filter by tenant
276
+ string tenant_id = 1;
277
+
278
+ // Filter by workflow
279
+ string workflow_id = 2;
280
+
281
+ // Filter by status
282
+ BudgetStatusType status = 3;
283
+
284
+ // Pagination
285
+ int32 page_size = 4;
286
+ string page_token = 5;
287
+ }
288
+
289
+ message ListBudgetsResponse {
290
+ repeated Budget budgets = 1;
291
+ string next_page_token = 2;
292
+ int32 total_count = 3;
293
+ }
294
+
295
+ // GetCostSummaryRequest retrieves cost summary for an envelope
296
+ message GetCostSummaryRequest {
297
+ string envelope_id = 1;
298
+ }
299
+
300
+ message GetCostSummaryResponse {
301
+ fulcrum.envelope.v1.CostSummary cost_summary = 1;
302
+ }
303
+
304
+ // GetSpendSummaryRequest retrieves aggregated spend for a tenant/workflow
305
+ message GetSpendSummaryRequest {
306
+ // Filter by tenant
307
+ string tenant_id = 1;
308
+
309
+ // Filter by workflow
310
+ string workflow_id = 2;
311
+
312
+ // Time range
313
+ google.protobuf.Timestamp start_time = 3;
314
+ google.protobuf.Timestamp end_time = 4;
315
+
316
+ // Grouping (e.g., by model, by day)
317
+ SpendGroupBy group_by = 5;
318
+ }
319
+
320
+ message GetSpendSummaryResponse {
321
+ SpendSummary summary = 1;
322
+
323
+ // Grouped summaries (if group_by specified)
324
+ repeated GroupedSpendSummary grouped_summaries = 2;
325
+ }
326
+
327
+ // SpendGroupBy defines how to group spend summaries
328
+ enum SpendGroupBy {
329
+ SPEND_GROUP_BY_UNSPECIFIED = 0;
330
+ SPEND_GROUP_BY_MODEL = 1;
331
+ SPEND_GROUP_BY_DAY = 2;
332
+ SPEND_GROUP_BY_WEEK = 3;
333
+ SPEND_GROUP_BY_MONTH = 4;
334
+ SPEND_GROUP_BY_WORKFLOW = 5;
335
+ }
336
+
337
+ // GroupedSpendSummary represents spend grouped by a dimension
338
+ message GroupedSpendSummary {
339
+ string group_key = 1;
340
+ SpendSummary summary = 2;
341
+ }
342
+
343
+ // GetBudgetStatusRequest retrieves current budget status
344
+ message GetBudgetStatusRequest {
345
+ string budget_id = 1;
346
+ }
347
+
348
+ message GetBudgetStatusResponse {
349
+ BudgetStatus status = 1;
350
+ }
351
+
352
+ // PredictCostRequest estimates cost for a planned execution
353
+ message PredictCostRequest {
354
+ // Tenant and workflow context
355
+ string tenant_id = 1;
356
+ string workflow_id = 2;
357
+
358
+ // Input for estimation
359
+ string input_text = 3;
360
+ int64 estimated_input_tokens = 4;
361
+
362
+ // Expected models to use
363
+ repeated string model_ids = 5;
364
+
365
+ // Historical data to use for prediction
366
+ bool use_historical_data = 6;
367
+ int32 lookback_days = 7; // Days of history to analyze
368
+ }
369
+
370
+ message PredictCostResponse {
371
+ // Predicted cost
372
+ CostPrediction prediction = 1;
373
+
374
+ // Whether prediction is based on historical data
375
+ bool historical_based = 2;
376
+
377
+ // Sample size used for prediction
378
+ int32 sample_size = 3;
379
+ }
380
+
381
+ // CostPrediction estimates future execution cost
382
+ message CostPrediction {
383
+ // Estimated tokens
384
+ int64 estimated_input_tokens = 1;
385
+ int64 estimated_output_tokens = 2;
386
+ int64 estimated_total_tokens = 3;
387
+
388
+ // Estimated cost
389
+ double estimated_cost_usd = 4;
390
+ double estimated_cost_usd_min = 5; // Lower bound
391
+ double estimated_cost_usd_max = 6; // Upper bound
392
+
393
+ // Confidence metrics
394
+ float confidence = 7; // 0.0 to 1.0
395
+ string confidence_level = 8; // "low", "medium", "high"
396
+
397
+ // Estimated execution time
398
+ int64 estimated_duration_seconds = 9;
399
+
400
+ // Per-model predictions
401
+ repeated ModelCostPrediction model_predictions = 10;
402
+ }
403
+
404
+ // ModelCostPrediction predicts cost for a specific model
405
+ message ModelCostPrediction {
406
+ string model_id = 1;
407
+ int64 estimated_tokens = 2;
408
+ double estimated_cost_usd = 3;
409
+ int32 estimated_calls = 4;
410
+ }
@@ -0,0 +1,162 @@
1
+ syntax = "proto3";
2
+
3
+ package fulcrum.envelope.v1;
4
+
5
+ option go_package = "github.com/fulcrum-io/fulcrum/pkg/envelope/v1";
6
+
7
+ import "google/protobuf/timestamp.proto";
8
+ import "google/protobuf/struct.proto";
9
+ import "events.proto";
10
+
11
+ // ExecutionEnvelope is Fulcrum's core abstraction.
12
+ // Every agent execution—regardless of framework—is wrapped in an envelope.
13
+ // Governance operates on envelopes, not raw framework executions.
14
+ message ExecutionEnvelope {
15
+ // Unique identifier for this envelope
16
+ string envelope_id = 1;
17
+
18
+ // Tenant isolation
19
+ string tenant_id = 2;
20
+
21
+ // Workflow identification (optional, for multi-step workflows)
22
+ string workflow_id = 3;
23
+
24
+ // Execution identification (unique per run)
25
+ string execution_id = 4;
26
+
27
+ // Governance context - budget, policies, limits
28
+ GovernanceContext governance = 5;
29
+
30
+ // Framework-specific context
31
+ FrameworkContext framework = 6;
32
+
33
+ // Current lifecycle state
34
+ EnvelopeStatus status = 7;
35
+
36
+ // Accumulated events during execution
37
+ repeated fulcrum.events.v1.FulcrumEvent events = 8;
38
+
39
+ // Cost tracking
40
+ CostSummary cost = 9;
41
+
42
+ // Timestamps
43
+ google.protobuf.Timestamp created_at = 10;
44
+ google.protobuf.Timestamp updated_at = 11;
45
+ google.protobuf.Timestamp completed_at = 12;
46
+
47
+ // Optional parent envelope (for sub-executions)
48
+ string parent_envelope_id = 13;
49
+
50
+ // Metadata (key-value pairs for extensibility)
51
+ map<string, string> metadata = 14;
52
+
53
+ // Trace context for distributed tracing (W3C Trace Context format)
54
+ map<string, string> trace_context = 15;
55
+ }
56
+
57
+ // GovernanceContext defines budget and policy constraints
58
+ message GovernanceContext {
59
+ // Budget constraints
60
+ string budget_id = 1;
61
+ int64 token_budget = 2; // Max tokens allowed
62
+ double cost_limit_usd = 3; // Max cost in USD
63
+ int64 timeout_seconds = 4; // Max execution time
64
+
65
+ // Policy constraints
66
+ string policy_set_id = 5; // Reference to policy ruleset
67
+ repeated string allowed_models = 6;
68
+ repeated string allowed_tools = 7;
69
+
70
+ // Rate limiting
71
+ int32 max_llm_calls = 8;
72
+ int32 max_tool_calls = 9;
73
+
74
+ // Compliance tags
75
+ repeated string compliance_tags = 10; // e.g., "pii-handling", "hipaa"
76
+ }
77
+
78
+ // FrameworkContext captures framework-specific execution details
79
+ message FrameworkContext {
80
+ // Which adapter is handling this execution
81
+ FrameworkType framework_type = 1;
82
+
83
+ // Reference to the native execution (opaque to Fulcrum)
84
+ string native_execution_ref = 2;
85
+
86
+ // Latest checkpoint ID (if checkpointing is supported)
87
+ string checkpoint_id = 3;
88
+
89
+ // Thread/session ID (for conversational workflows)
90
+ string thread_id = 4;
91
+
92
+ // Framework-specific configuration (opaque payload)
93
+ google.protobuf.Struct native_config = 5;
94
+ }
95
+
96
+ // FrameworkType identifies the orchestration framework
97
+ enum FrameworkType {
98
+ FRAMEWORK_TYPE_UNSPECIFIED = 0;
99
+ FRAMEWORK_TYPE_LANGGRAPH = 1;
100
+ FRAMEWORK_TYPE_MICROSOFT = 2;
101
+ FRAMEWORK_TYPE_CREWAI = 3;
102
+ FRAMEWORK_TYPE_AUTOGEN = 4;
103
+ FRAMEWORK_TYPE_A2A_PROXY = 5;
104
+ FRAMEWORK_TYPE_CUSTOM = 99;
105
+ }
106
+
107
+ // EnvelopeStatus tracks execution lifecycle
108
+ enum EnvelopeStatus {
109
+ ENVELOPE_STATUS_UNSPECIFIED = 0;
110
+ ENVELOPE_STATUS_PENDING = 1; // Created, not yet authorized
111
+ ENVELOPE_STATUS_AUTHORIZED = 2; // Passed policy check, ready to run
112
+ ENVELOPE_STATUS_RUNNING = 3; // Currently executing
113
+ ENVELOPE_STATUS_PAUSED = 4; // Suspended (human-in-the-loop)
114
+ ENVELOPE_STATUS_COMPLETED = 5; // Successfully finished
115
+ ENVELOPE_STATUS_FAILED = 6; // Error during execution
116
+ ENVELOPE_STATUS_TERMINATED = 7; // Forcefully stopped
117
+ ENVELOPE_STATUS_BUDGET_EXCEEDED = 8; // Killed due to budget
118
+ ENVELOPE_STATUS_POLICY_VIOLATION = 9; // Killed due to policy
119
+ ENVELOPE_STATUS_TIMEOUT = 10; // Killed due to timeout
120
+ }
121
+
122
+ // CostSummary aggregates cost information
123
+ message CostSummary {
124
+ int64 total_input_tokens = 1;
125
+ int64 total_output_tokens = 2;
126
+ double total_cost_usd = 3;
127
+ int32 llm_call_count = 4;
128
+ int32 tool_call_count = 5;
129
+
130
+ // Per-model breakdown
131
+ repeated ModelCost model_costs = 6;
132
+ }
133
+
134
+ // ModelCost tracks cost per model
135
+ message ModelCost {
136
+ string model_id = 1;
137
+ int64 input_tokens = 2;
138
+ int64 output_tokens = 3;
139
+ double cost_usd = 4;
140
+ int32 call_count = 5;
141
+ }
142
+
143
+ // Checkpoint captures execution state for recovery
144
+ message Checkpoint {
145
+ string checkpoint_id = 1;
146
+ string envelope_id = 2;
147
+ google.protobuf.Timestamp created_at = 3;
148
+
149
+ // State hash for integrity verification
150
+ string state_hash = 4;
151
+
152
+ // Serialized state (framework-specific format)
153
+ bytes state_data = 5;
154
+ int64 state_size_bytes = 6;
155
+
156
+ // Position in execution
157
+ string node_id = 7; // Current node/step
158
+ int32 iteration = 8; // Loop iteration if applicable
159
+
160
+ // Cost at checkpoint time
161
+ CostSummary cost_snapshot = 9;
162
+ }
@@ -0,0 +1,52 @@
1
+ syntax = "proto3";
2
+
3
+ package fulcrum.envelope.v1;
4
+
5
+ option go_package = "github.com/fulcrum-io/fulcrum/pkg/envelope/v1";
6
+
7
+
8
+ import "fulcrum/envelope/v1/envelope.proto";
9
+
10
+ service EnvelopeService {
11
+ // CreateEnvelope initializes a new execution envelope
12
+ rpc CreateEnvelope(CreateEnvelopeRequest) returns (CreateEnvelopeResponse);
13
+
14
+ // GetEnvelope retrieves an envelope by ID
15
+ rpc GetEnvelope(GetEnvelopeRequest) returns (GetEnvelopeResponse);
16
+
17
+ // UpdateEnvelopeStatus updates the status of an envelope
18
+ rpc UpdateEnvelopeStatus(UpdateEnvelopeStatusRequest) returns (UpdateEnvelopeStatusResponse);
19
+ }
20
+
21
+ message CreateEnvelopeRequest {
22
+ string tenant_id = 1;
23
+ string budget_id = 2; // Optional: specific budget to use
24
+
25
+ // The intent/request that needs an envelope
26
+ string adapter_type = 3; // e.g., "custom", "langchain"
27
+
28
+ // Metadata for policy evaluation (e.g. tool_name, model_name)
29
+ map<string, string> metadata = 4;
30
+ }
31
+
32
+ message CreateEnvelopeResponse {
33
+ ExecutionEnvelope envelope = 1;
34
+ }
35
+
36
+ message GetEnvelopeRequest {
37
+ string envelope_id = 1;
38
+ }
39
+
40
+ message GetEnvelopeResponse {
41
+ ExecutionEnvelope envelope = 1;
42
+ }
43
+
44
+ message UpdateEnvelopeStatusRequest {
45
+ string envelope_id = 1;
46
+ EnvelopeStatus status = 2;
47
+ string reason = 3; // Optional reason for status change
48
+ }
49
+
50
+ message UpdateEnvelopeStatusResponse {
51
+ ExecutionEnvelope envelope = 1;
52
+ }