@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.
- package/CHANGELOG.md +28 -0
- package/LICENSE +98 -0
- package/README.md +94 -0
- package/dist/Icon/r +0 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.js +144 -0
- package/package.json +46 -0
- package/proto/events.proto +197 -0
- package/proto/fulcrum/bridge/v1/bridge.proto +316 -0
- package/proto/fulcrum/checkpoint/v1/checkpoint_service.proto +368 -0
- package/proto/fulcrum/cost/v1/cost_service.proto +410 -0
- package/proto/fulcrum/envelope/v1/envelope.proto +162 -0
- package/proto/fulcrum/envelope/v1/envelope_service.proto +52 -0
- package/proto/fulcrum/eventstore/v1/eventstore.proto +254 -0
- package/proto/fulcrum/policy/v1/policy_service.proto +555 -0
- package/proto/fulcrum/tenant/v1/tenant_service.proto +57 -0
- package/proto/google/api/annotations.proto +31 -0
- package/proto/google/api/http.proto +370 -0
|
@@ -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
|
+
}
|