@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
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to the Fulcrum TypeScript SDK will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2025-12-26
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Initial release of Fulcrum TypeScript SDK
|
|
12
|
+
- `FulcrumClient` class for connecting to Fulcrum gRPC server
|
|
13
|
+
- `Envelope` class for workflow governance wrapping
|
|
14
|
+
- Policy evaluation with `guard()` method
|
|
15
|
+
- Event logging with `log()` method
|
|
16
|
+
- TypeScript type definitions for all interfaces
|
|
17
|
+
- Support for FAIL_OPEN and FAIL_CLOSED failure modes
|
|
18
|
+
- Configurable timeout and API key authentication
|
|
19
|
+
- Complete Protocol Buffer definitions included
|
|
20
|
+
|
|
21
|
+
### Features
|
|
22
|
+
- Real-time policy enforcement for AI agents
|
|
23
|
+
- Cost tracking and budget management
|
|
24
|
+
- Audit trail and compliance logging
|
|
25
|
+
- Fail-safe error handling
|
|
26
|
+
- Full TypeScript support with type definitions
|
|
27
|
+
|
|
28
|
+
[0.1.0]: https://github.com/fulcrum-io/fulcrum/releases/tag/sdk-typescript-v0.1.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity.
|
|
18
|
+
|
|
19
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
20
|
+
exercising permissions granted by this License.
|
|
21
|
+
|
|
22
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
23
|
+
including but not limited to software source code, documentation
|
|
24
|
+
source, and configuration files.
|
|
25
|
+
|
|
26
|
+
"Object" form shall mean any form resulting from mechanical
|
|
27
|
+
transformation or translation of a Source form.
|
|
28
|
+
|
|
29
|
+
"Work" shall mean the work of authorship made available under the
|
|
30
|
+
License.
|
|
31
|
+
|
|
32
|
+
"Derivative Works" shall mean any work that is based on the Work.
|
|
33
|
+
|
|
34
|
+
"Contribution" shall mean any work of authorship submitted to the
|
|
35
|
+
Licensor for inclusion in the Work.
|
|
36
|
+
|
|
37
|
+
"Contributor" shall mean Licensor and any Legal Entity on behalf of
|
|
38
|
+
whom a Contribution has been received by Licensor.
|
|
39
|
+
|
|
40
|
+
2. Grant of Copyright License. Subject to the terms of this License,
|
|
41
|
+
each Contributor hereby grants to You a perpetual, worldwide,
|
|
42
|
+
non-exclusive, no-charge, royalty-free, irrevocable copyright license
|
|
43
|
+
to reproduce, prepare Derivative Works of, publicly display, publicly
|
|
44
|
+
perform, sublicense, and distribute the Work and such Derivative Works
|
|
45
|
+
in Source or Object form.
|
|
46
|
+
|
|
47
|
+
3. Grant of Patent License. Subject to the terms of this License,
|
|
48
|
+
each Contributor hereby grants to You a perpetual, worldwide,
|
|
49
|
+
non-exclusive, no-charge, royalty-free, irrevocable patent license
|
|
50
|
+
to make, have made, use, offer to sell, sell, import, and otherwise
|
|
51
|
+
transfer the Work.
|
|
52
|
+
|
|
53
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
54
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
55
|
+
modifications, and in Source or Object form, provided that You
|
|
56
|
+
meet the following conditions:
|
|
57
|
+
|
|
58
|
+
(a) You must give any other recipients of the Work or
|
|
59
|
+
Derivative Works a copy of this License; and
|
|
60
|
+
|
|
61
|
+
(b) You must cause any modified files to carry prominent notices
|
|
62
|
+
stating that You changed the files; and
|
|
63
|
+
|
|
64
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
65
|
+
that You distribute, all copyright, patent, trademark, and
|
|
66
|
+
attribution notices from the Source form of the Work.
|
|
67
|
+
|
|
68
|
+
5. Submission of Contributions. Any Contribution intentionally
|
|
69
|
+
submitted for inclusion in the Work shall be under the terms of
|
|
70
|
+
this License.
|
|
71
|
+
|
|
72
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
73
|
+
names, trademarks, service marks, or product names of the Licensor.
|
|
74
|
+
|
|
75
|
+
7. Disclaimer of Warranty. THE WORK IS PROVIDED "AS IS", WITHOUT
|
|
76
|
+
WARRANTIES OR CONDITIONS OF ANY KIND.
|
|
77
|
+
|
|
78
|
+
8. Limitation of Liability. IN NO EVENT SHALL ANY CONTRIBUTOR BE
|
|
79
|
+
LIABLE FOR DAMAGES ARISING FROM USE OF THE WORK.
|
|
80
|
+
|
|
81
|
+
9. Accepting Warranty or Additional Liability. You may offer warranty
|
|
82
|
+
or additional liability obligations for a fee.
|
|
83
|
+
|
|
84
|
+
END OF TERMS AND CONDITIONS
|
|
85
|
+
|
|
86
|
+
Copyright 2025 Fulcrum Contributors
|
|
87
|
+
|
|
88
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
89
|
+
you may not use this file except in compliance with the License.
|
|
90
|
+
You may obtain a copy of the License at
|
|
91
|
+
|
|
92
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
93
|
+
|
|
94
|
+
Unless required by applicable law or agreed to in writing, software
|
|
95
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
96
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
97
|
+
See the License for the specific language governing permissions and
|
|
98
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Fulcrum TypeScript SDK
|
|
2
|
+
|
|
3
|
+
> Intelligent AI Governance for Enterprise Agents
|
|
4
|
+
|
|
5
|
+
[](https://badge.fury.io/js/%40fulcrum-governance%2Fsdk)
|
|
6
|
+
[](https://nodejs.org/)
|
|
7
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @fulcrum-governance/sdk
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { FulcrumClient } from '@fulcrum-governance/sdk';
|
|
19
|
+
|
|
20
|
+
// Initialize client
|
|
21
|
+
const client = new FulcrumClient({
|
|
22
|
+
host: 'your-fulcrum-server:50051',
|
|
23
|
+
apiKey: 'your-api-key',
|
|
24
|
+
onFailure: 'FAIL_OPEN' // or 'FAIL_CLOSED'
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// Wrap agent executions in governance envelopes
|
|
28
|
+
const envelope = client.envelope({
|
|
29
|
+
workflowId: 'customer-support-bot',
|
|
30
|
+
tenantId: 'your-tenant-id'
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Check if action is allowed before executing
|
|
34
|
+
const allowed = await envelope.guard('send_email', userMessage);
|
|
35
|
+
|
|
36
|
+
if (allowed) {
|
|
37
|
+
// Action approved - proceed
|
|
38
|
+
const result = await sendEmail(userMessage);
|
|
39
|
+
envelope.log('email_sent', { recipient: email, status: 'success' });
|
|
40
|
+
} else {
|
|
41
|
+
// Action blocked by policy
|
|
42
|
+
envelope.log('action_blocked', { reason: 'policy_violation' });
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Features
|
|
47
|
+
|
|
48
|
+
- **Policy Enforcement**: Real-time governance checks before agent actions
|
|
49
|
+
- **Cost Tracking**: Monitor and control LLM spending per workflow
|
|
50
|
+
- **Audit Trail**: Complete execution history for compliance
|
|
51
|
+
- **Fail-Safe Modes**: Configurable FAIL_OPEN or FAIL_CLOSED behavior
|
|
52
|
+
- **TypeScript Support**: Full type definitions included
|
|
53
|
+
|
|
54
|
+
## API Reference
|
|
55
|
+
|
|
56
|
+
### FulcrumClient
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
interface FulcrumClientOptions {
|
|
60
|
+
host: string; // gRPC server address (e.g., 'localhost:50051')
|
|
61
|
+
apiKey?: string; // Authentication key
|
|
62
|
+
onFailure?: 'FAIL_OPEN' | 'FAIL_CLOSED'; // Behavior on errors
|
|
63
|
+
timeoutMs?: number; // Request timeout (default: 500ms)
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Envelope
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
interface EnvelopeOptions {
|
|
71
|
+
workflowId: string; // Identifier for the workflow
|
|
72
|
+
executionId?: string; // Auto-generated if not provided
|
|
73
|
+
tenantId?: string; // Defaults to 'default-tenant'
|
|
74
|
+
metadata?: Record<string, string>; // Additional context
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Methods
|
|
79
|
+
|
|
80
|
+
**`envelope.guard(actionName: string, inputText: string, metadata?: Record<string, string>): Promise<boolean>`**
|
|
81
|
+
|
|
82
|
+
Checks if an action is allowed by current policies.
|
|
83
|
+
|
|
84
|
+
**`envelope.log(eventType: string, payload: Record<string, any>): void`**
|
|
85
|
+
|
|
86
|
+
Logs an event for audit trail and observability.
|
|
87
|
+
|
|
88
|
+
## Documentation
|
|
89
|
+
|
|
90
|
+
Full documentation: [https://docs.fulcrum.dev](https://docs.fulcrum.dev)
|
|
91
|
+
|
|
92
|
+
## License
|
|
93
|
+
|
|
94
|
+
Apache 2.0
|
package/dist/Icon/r
ADDED
|
File without changes
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export interface FulcrumClientOptions {
|
|
2
|
+
host: string;
|
|
3
|
+
apiKey?: string;
|
|
4
|
+
onFailure?: 'FAIL_OPEN' | 'FAIL_CLOSED';
|
|
5
|
+
timeoutMs?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface EnvelopeOptions {
|
|
8
|
+
workflowId: string;
|
|
9
|
+
executionId?: string;
|
|
10
|
+
tenantId?: string;
|
|
11
|
+
metadata?: Record<string, string>;
|
|
12
|
+
}
|
|
13
|
+
export interface GuardResult {
|
|
14
|
+
allowed: boolean;
|
|
15
|
+
decision: string;
|
|
16
|
+
reason: string;
|
|
17
|
+
}
|
|
18
|
+
export declare class FulcrumClient {
|
|
19
|
+
private host;
|
|
20
|
+
private apiKey?;
|
|
21
|
+
private onFailure;
|
|
22
|
+
private timeoutMs;
|
|
23
|
+
private policyClient;
|
|
24
|
+
constructor(options: FulcrumClientOptions);
|
|
25
|
+
private initClients;
|
|
26
|
+
private getMetadata;
|
|
27
|
+
envelope(options: EnvelopeOptions): Envelope;
|
|
28
|
+
evaluatePolicy(context: {
|
|
29
|
+
tenantId: string;
|
|
30
|
+
workflowId: string;
|
|
31
|
+
inputText?: string;
|
|
32
|
+
attributes?: Record<string, string>;
|
|
33
|
+
}): Promise<GuardResult>;
|
|
34
|
+
shutdown(): void;
|
|
35
|
+
}
|
|
36
|
+
export declare class Envelope {
|
|
37
|
+
private client;
|
|
38
|
+
private executionId;
|
|
39
|
+
private tenantId;
|
|
40
|
+
private workflowId;
|
|
41
|
+
private envelopeId;
|
|
42
|
+
constructor(client: FulcrumClient, options: Required<EnvelopeOptions>);
|
|
43
|
+
guard(actionName: string, inputText?: string, metadata?: Record<string, string>): Promise<boolean>;
|
|
44
|
+
log(eventType: string, payload?: Record<string, any>): void;
|
|
45
|
+
}
|
|
46
|
+
export default FulcrumClient;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.Envelope = exports.FulcrumClient = void 0;
|
|
37
|
+
const grpc = __importStar(require("@grpc/grpc-js"));
|
|
38
|
+
const protoLoader = __importStar(require("@grpc/proto-loader"));
|
|
39
|
+
const uuid_1 = require("uuid");
|
|
40
|
+
const path = __importStar(require("path"));
|
|
41
|
+
class FulcrumClient {
|
|
42
|
+
constructor(options) {
|
|
43
|
+
this.host = options.host;
|
|
44
|
+
this.apiKey = options.apiKey;
|
|
45
|
+
this.onFailure = options.onFailure || 'FAIL_OPEN';
|
|
46
|
+
this.timeoutMs = options.timeoutMs || 500;
|
|
47
|
+
this.initClients();
|
|
48
|
+
}
|
|
49
|
+
initClients() {
|
|
50
|
+
// Proto files are in ../proto relative to dist/index.js
|
|
51
|
+
const protoPath = path.join(__dirname, '../proto');
|
|
52
|
+
const policyProto = protoLoader.loadSync(path.join(protoPath, 'fulcrum/policy/v1/policy_service.proto'), {
|
|
53
|
+
keepCase: true,
|
|
54
|
+
longs: String,
|
|
55
|
+
enums: String,
|
|
56
|
+
defaults: true,
|
|
57
|
+
oneofs: true,
|
|
58
|
+
includeDirs: [protoPath] // Add includeDirs to resolve imports
|
|
59
|
+
});
|
|
60
|
+
const policyPackage = grpc.loadPackageDefinition(policyProto);
|
|
61
|
+
this.policyClient = new policyPackage.fulcrum.policy.v1.PolicyService(this.host, grpc.credentials.createInsecure());
|
|
62
|
+
}
|
|
63
|
+
getMetadata() {
|
|
64
|
+
const metadata = new grpc.Metadata();
|
|
65
|
+
if (this.apiKey) {
|
|
66
|
+
metadata.add('x-api-key', this.apiKey);
|
|
67
|
+
}
|
|
68
|
+
return metadata;
|
|
69
|
+
}
|
|
70
|
+
envelope(options) {
|
|
71
|
+
return new Envelope(this, {
|
|
72
|
+
...options,
|
|
73
|
+
executionId: options.executionId || (0, uuid_1.v4)(),
|
|
74
|
+
tenantId: options.tenantId || 'default-tenant',
|
|
75
|
+
metadata: options.metadata || {},
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
async evaluatePolicy(context) {
|
|
79
|
+
return new Promise((resolve) => {
|
|
80
|
+
const deadline = new Date(Date.now() + this.timeoutMs);
|
|
81
|
+
this.policyClient.EvaluatePolicies(// Changed from EvaluatePolicy to EvaluatePolicies as per proto
|
|
82
|
+
{
|
|
83
|
+
context: {
|
|
84
|
+
tenant_id: context.tenantId,
|
|
85
|
+
workflow_id: context.workflowId,
|
|
86
|
+
input_text: context.inputText,
|
|
87
|
+
attributes: context.attributes
|
|
88
|
+
}
|
|
89
|
+
}, this.getMetadata(), { deadline }, (err, response) => {
|
|
90
|
+
if (err) {
|
|
91
|
+
console.error('Policy evaluation failed:', err);
|
|
92
|
+
if (this.onFailure === 'FAIL_OPEN') {
|
|
93
|
+
resolve({ allowed: true, decision: 'ALLOW', reason: `Fail-safe: ${err.message}` });
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
resolve({ allowed: false, decision: 'DENY', reason: `Fail-safe (Closed): ${err.message}` });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
// Mapping Logic from EvaluatePoliciesResponse
|
|
101
|
+
// message EvaluatePoliciesResponse {
|
|
102
|
+
// repeated PolicyDecision decisions = 1;
|
|
103
|
+
// EvaluationDecision final_decision = 2; // ALLOW, DENY, ...
|
|
104
|
+
// }
|
|
105
|
+
const isAllowed = response.final_decision === 'EVALUATION_DECISION_ALLOW' || response.final_decision === 'ALLOW'; // Check enum string mapping
|
|
106
|
+
resolve({
|
|
107
|
+
allowed: isAllowed,
|
|
108
|
+
decision: response.final_decision,
|
|
109
|
+
reason: "Policy Evaluation", // Response doesn't have top-level reason, maybe aggregate from decisions?
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
shutdown() {
|
|
116
|
+
// Cleanup if needed
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.FulcrumClient = FulcrumClient;
|
|
120
|
+
class Envelope {
|
|
121
|
+
constructor(client, options) {
|
|
122
|
+
this.client = client;
|
|
123
|
+
this.executionId = options.executionId;
|
|
124
|
+
this.tenantId = options.tenantId;
|
|
125
|
+
this.workflowId = options.workflowId;
|
|
126
|
+
this.envelopeId = (0, uuid_1.v4)();
|
|
127
|
+
}
|
|
128
|
+
async guard(actionName, inputText = '', metadata) {
|
|
129
|
+
const result = await this.client.evaluatePolicy({
|
|
130
|
+
tenantId: this.tenantId,
|
|
131
|
+
workflowId: this.workflowId,
|
|
132
|
+
inputText,
|
|
133
|
+
attributes: { ...metadata, action: actionName },
|
|
134
|
+
});
|
|
135
|
+
return result.allowed;
|
|
136
|
+
}
|
|
137
|
+
log(eventType, payload = {}) {
|
|
138
|
+
// Async event logging - fire and forget
|
|
139
|
+
console.log(`[Fulcrum] ${this.envelopeId} | ${eventType}:`, payload);
|
|
140
|
+
// TODO: Implement actual event publishing
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
exports.Envelope = Envelope;
|
|
144
|
+
exports.default = FulcrumClient;
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fulcrum_io/sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "TypeScript SDK for Fulcrum - Intelligent AI Governance Platform",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"test": "jest",
|
|
10
|
+
"lint": "eslint src/",
|
|
11
|
+
"prepublishOnly": "npm run build"
|
|
12
|
+
},
|
|
13
|
+
"keywords": ["ai", "governance", "llm", "agents", "safety", "grpc"],
|
|
14
|
+
"author": "Fulcrum Team <hello@fulcrum.dev>",
|
|
15
|
+
"license": "Apache-2.0",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/fulcrum-io/fulcrum.git",
|
|
19
|
+
"directory": "sdk/typescript"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@grpc/grpc-js": "^1.9.0",
|
|
23
|
+
"@grpc/proto-loader": "^0.7.0",
|
|
24
|
+
"uuid": "^9.0.0"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/node": "^20.0.0",
|
|
28
|
+
"@types/uuid": "^9.0.0",
|
|
29
|
+
"typescript": "^5.3.0",
|
|
30
|
+
"jest": "^29.0.0",
|
|
31
|
+
"@types/jest": "^29.0.0",
|
|
32
|
+
"ts-jest": "^29.0.0",
|
|
33
|
+
"eslint": "^8.0.0",
|
|
34
|
+
"@typescript-eslint/eslint-plugin": "^6.0.0"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=18.0.0"
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist/",
|
|
41
|
+
"proto/",
|
|
42
|
+
"README.md",
|
|
43
|
+
"LICENSE",
|
|
44
|
+
"CHANGELOG.md"
|
|
45
|
+
]
|
|
46
|
+
}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package fulcrum.events.v1;
|
|
4
|
+
|
|
5
|
+
option go_package = "github.com/fulcrum-io/fulcrum/pkg/events/v1";
|
|
6
|
+
|
|
7
|
+
import "google/protobuf/timestamp.proto";
|
|
8
|
+
import "google/protobuf/struct.proto";
|
|
9
|
+
|
|
10
|
+
// FulcrumEvent is the normalized event schema.
|
|
11
|
+
// All adapters emit events in this format regardless of framework.
|
|
12
|
+
message FulcrumEvent {
|
|
13
|
+
// Event identification
|
|
14
|
+
string event_id = 1;
|
|
15
|
+
string envelope_id = 2;
|
|
16
|
+
string tenant_id = 14;
|
|
17
|
+
string workflow_id = 15;
|
|
18
|
+
google.protobuf.Timestamp timestamp = 3;
|
|
19
|
+
|
|
20
|
+
// Event classification
|
|
21
|
+
EventType event_type = 4;
|
|
22
|
+
EventSeverity severity = 5;
|
|
23
|
+
|
|
24
|
+
// Token tracking (present for LLM events)
|
|
25
|
+
TokenInfo tokens = 6;
|
|
26
|
+
|
|
27
|
+
// Checkpoint reference (present for checkpoint events)
|
|
28
|
+
CheckpointRef checkpoint = 7;
|
|
29
|
+
|
|
30
|
+
// Error information (present for error events)
|
|
31
|
+
ErrorInfo error = 8;
|
|
32
|
+
|
|
33
|
+
// Tool invocation details (present for tool events)
|
|
34
|
+
ToolInfo tool = 9;
|
|
35
|
+
|
|
36
|
+
// Policy evaluation result (present for policy events)
|
|
37
|
+
PolicyResult policy = 10;
|
|
38
|
+
|
|
39
|
+
// Budget status (present for budget events)
|
|
40
|
+
BudgetStatusEvent budget = 11;
|
|
41
|
+
|
|
42
|
+
// Framework-specific payload (opaque to control plane)
|
|
43
|
+
google.protobuf.Struct native_payload = 12;
|
|
44
|
+
|
|
45
|
+
// Trace context for distributed tracing
|
|
46
|
+
TraceContext trace = 13;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// EventType categorizes the event
|
|
50
|
+
enum EventType {
|
|
51
|
+
EVENT_TYPE_UNSPECIFIED = 0;
|
|
52
|
+
|
|
53
|
+
// Execution lifecycle
|
|
54
|
+
EVENT_TYPE_EXECUTION_STARTED = 1;
|
|
55
|
+
EVENT_TYPE_EXECUTION_COMPLETED = 2;
|
|
56
|
+
EVENT_TYPE_EXECUTION_FAILED = 3;
|
|
57
|
+
EVENT_TYPE_EXECUTION_PAUSED = 4;
|
|
58
|
+
EVENT_TYPE_EXECUTION_RESUMED = 5;
|
|
59
|
+
EVENT_TYPE_EXECUTION_TERMINATED = 6;
|
|
60
|
+
|
|
61
|
+
// LLM interactions
|
|
62
|
+
EVENT_TYPE_LLM_CALL_STARTED = 10;
|
|
63
|
+
EVENT_TYPE_LLM_CALL_COMPLETED = 11;
|
|
64
|
+
EVENT_TYPE_LLM_CALL_FAILED = 12;
|
|
65
|
+
EVENT_TYPE_LLM_STREAMING_CHUNK = 13;
|
|
66
|
+
|
|
67
|
+
// Tool interactions
|
|
68
|
+
EVENT_TYPE_TOOL_INVOKED = 20;
|
|
69
|
+
EVENT_TYPE_TOOL_COMPLETED = 21;
|
|
70
|
+
EVENT_TYPE_TOOL_FAILED = 22;
|
|
71
|
+
|
|
72
|
+
// Checkpointing
|
|
73
|
+
EVENT_TYPE_CHECKPOINT_CREATED = 30;
|
|
74
|
+
EVENT_TYPE_CHECKPOINT_RESTORED = 31;
|
|
75
|
+
|
|
76
|
+
// Budget events
|
|
77
|
+
EVENT_TYPE_BUDGET_WARNING = 40; // 80% threshold
|
|
78
|
+
EVENT_TYPE_BUDGET_EXCEEDED = 41;
|
|
79
|
+
EVENT_TYPE_BUDGET_RESET = 42;
|
|
80
|
+
|
|
81
|
+
// Policy events
|
|
82
|
+
EVENT_TYPE_POLICY_EVALUATED = 50;
|
|
83
|
+
EVENT_TYPE_POLICY_VIOLATION = 51;
|
|
84
|
+
EVENT_TYPE_POLICY_WARNING = 52;
|
|
85
|
+
|
|
86
|
+
// Agent coordination (multi-agent)
|
|
87
|
+
EVENT_TYPE_AGENT_HANDOFF = 60;
|
|
88
|
+
EVENT_TYPE_AGENT_SPAWN = 61;
|
|
89
|
+
EVENT_TYPE_AGENT_JOIN = 62;
|
|
90
|
+
|
|
91
|
+
// Custom events
|
|
92
|
+
EVENT_TYPE_CUSTOM = 99;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// EventSeverity for filtering and alerting
|
|
96
|
+
enum EventSeverity {
|
|
97
|
+
EVENT_SEVERITY_UNSPECIFIED = 0;
|
|
98
|
+
EVENT_SEVERITY_DEBUG = 1;
|
|
99
|
+
EVENT_SEVERITY_INFO = 2;
|
|
100
|
+
EVENT_SEVERITY_WARNING = 3;
|
|
101
|
+
EVENT_SEVERITY_ERROR = 4;
|
|
102
|
+
EVENT_SEVERITY_CRITICAL = 5;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// TokenInfo captures LLM token consumption
|
|
106
|
+
message TokenInfo {
|
|
107
|
+
string model_id = 1;
|
|
108
|
+
int64 input_tokens = 2;
|
|
109
|
+
int64 output_tokens = 3;
|
|
110
|
+
double cost_usd = 4;
|
|
111
|
+
|
|
112
|
+
// Latency metrics
|
|
113
|
+
int64 time_to_first_token_ms = 5;
|
|
114
|
+
int64 total_latency_ms = 6;
|
|
115
|
+
|
|
116
|
+
// For streaming responses
|
|
117
|
+
bool is_streaming = 7;
|
|
118
|
+
int32 chunk_index = 8;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// CheckpointRef references a checkpoint
|
|
122
|
+
message CheckpointRef {
|
|
123
|
+
string checkpoint_id = 1;
|
|
124
|
+
string state_hash = 2;
|
|
125
|
+
int64 size_bytes = 3;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// ErrorInfo captures error details
|
|
129
|
+
message ErrorInfo {
|
|
130
|
+
string code = 1;
|
|
131
|
+
string message = 2;
|
|
132
|
+
bool recoverable = 3;
|
|
133
|
+
string stack_trace = 4;
|
|
134
|
+
|
|
135
|
+
// Retry information
|
|
136
|
+
int32 retry_count = 5;
|
|
137
|
+
bool will_retry = 6;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// ToolInfo captures tool invocation details
|
|
141
|
+
message ToolInfo {
|
|
142
|
+
string tool_name = 1;
|
|
143
|
+
string tool_id = 2;
|
|
144
|
+
|
|
145
|
+
// Input/output (sanitized for logging)
|
|
146
|
+
google.protobuf.Struct input = 3;
|
|
147
|
+
google.protobuf.Struct output = 4;
|
|
148
|
+
|
|
149
|
+
// Execution metrics
|
|
150
|
+
int64 latency_ms = 5;
|
|
151
|
+
bool success = 6;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// PolicyResult captures policy evaluation
|
|
155
|
+
message PolicyResult {
|
|
156
|
+
string policy_id = 1;
|
|
157
|
+
string rule_id = 2;
|
|
158
|
+
PolicyDecision decision = 3;
|
|
159
|
+
string reason = 4;
|
|
160
|
+
|
|
161
|
+
// What triggered the evaluation
|
|
162
|
+
string trigger = 5;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
enum PolicyDecision {
|
|
166
|
+
POLICY_DECISION_UNSPECIFIED = 0;
|
|
167
|
+
POLICY_DECISION_ALLOW = 1;
|
|
168
|
+
POLICY_DECISION_DENY = 2;
|
|
169
|
+
POLICY_DECISION_WARN = 3;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// BudgetStatusEvent captures budget state for events
|
|
173
|
+
message BudgetStatusEvent {
|
|
174
|
+
string budget_id = 1;
|
|
175
|
+
|
|
176
|
+
// Current consumption
|
|
177
|
+
int64 tokens_used = 2;
|
|
178
|
+
int64 tokens_remaining = 3;
|
|
179
|
+
double cost_used_usd = 4;
|
|
180
|
+
double cost_remaining_usd = 5;
|
|
181
|
+
|
|
182
|
+
// Percentage used
|
|
183
|
+
double percentage_used = 6;
|
|
184
|
+
|
|
185
|
+
// Threshold that triggered this event
|
|
186
|
+
double threshold_percentage = 7;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// TraceContext for distributed tracing (W3C Trace Context compatible)
|
|
190
|
+
message TraceContext {
|
|
191
|
+
string trace_id = 1;
|
|
192
|
+
string span_id = 2;
|
|
193
|
+
string parent_span_id = 3;
|
|
194
|
+
|
|
195
|
+
// Baggage for cross-service context
|
|
196
|
+
map<string, string> baggage = 4;
|
|
197
|
+
}
|