@creedspace/sdk 1.0.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/README.md +195 -0
- package/dist/index.d.mts +205 -0
- package/dist/index.d.ts +205 -0
- package/dist/index.js +146 -0
- package/dist/index.mjs +118 -0
- package/package.json +55 -0
- package/src/index.test.ts +400 -0
- package/src/index.ts +364 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
CreedError: () => CreedError,
|
|
24
|
+
computeArgsHash: () => computeArgsHash,
|
|
25
|
+
createClient: () => createClient,
|
|
26
|
+
default: () => index_default,
|
|
27
|
+
isTokenExpired: () => isTokenExpired
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(index_exports);
|
|
30
|
+
var CreedError = class extends Error {
|
|
31
|
+
constructor(message, code, statusCode) {
|
|
32
|
+
super(message);
|
|
33
|
+
this.code = code;
|
|
34
|
+
this.statusCode = statusCode;
|
|
35
|
+
this.name = "CreedError";
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
function createClient(options) {
|
|
39
|
+
const {
|
|
40
|
+
apiKey,
|
|
41
|
+
baseUrl = "https://api.creed.space",
|
|
42
|
+
fetch: customFetch = fetch,
|
|
43
|
+
timeoutMs = 3e4
|
|
44
|
+
} = options;
|
|
45
|
+
if (!apiKey) {
|
|
46
|
+
throw new CreedError("API key is required", "MISSING_API_KEY");
|
|
47
|
+
}
|
|
48
|
+
async function request(endpoint, method, body) {
|
|
49
|
+
const controller = new AbortController();
|
|
50
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
51
|
+
try {
|
|
52
|
+
const response = await customFetch(`${baseUrl}${endpoint}`, {
|
|
53
|
+
method,
|
|
54
|
+
headers: {
|
|
55
|
+
"Content-Type": "application/json",
|
|
56
|
+
Authorization: `Bearer ${apiKey}`,
|
|
57
|
+
"X-Creed-SDK": "typescript/1.0.0"
|
|
58
|
+
},
|
|
59
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
60
|
+
signal: controller.signal
|
|
61
|
+
});
|
|
62
|
+
if (!response.ok) {
|
|
63
|
+
const errorBody = await response.text();
|
|
64
|
+
throw new CreedError(
|
|
65
|
+
errorBody || `Request failed with status ${response.status}`,
|
|
66
|
+
"REQUEST_FAILED",
|
|
67
|
+
response.status
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
return response.json();
|
|
71
|
+
} catch (error) {
|
|
72
|
+
if (error instanceof CreedError) throw error;
|
|
73
|
+
if (error.name === "AbortError") {
|
|
74
|
+
throw new CreedError("Request timed out", "TIMEOUT");
|
|
75
|
+
}
|
|
76
|
+
throw new CreedError(error.message, "NETWORK_ERROR");
|
|
77
|
+
} finally {
|
|
78
|
+
clearTimeout(timeoutId);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
async decide(req) {
|
|
83
|
+
const response = await request("/v1/decide", "POST", {
|
|
84
|
+
tool_name: req.toolName,
|
|
85
|
+
arguments: req.arguments,
|
|
86
|
+
constitution_id: req.constitutionId || "default",
|
|
87
|
+
context: req.context || {}
|
|
88
|
+
});
|
|
89
|
+
if (response.decision === "ALLOW" && req.onAllow) {
|
|
90
|
+
await req.onAllow(response);
|
|
91
|
+
} else if (response.decision === "DENY" && req.onDeny) {
|
|
92
|
+
await req.onDeny(response);
|
|
93
|
+
} else if (response.decision === "REQUIRE_HUMAN" && req.onRequireHuman) {
|
|
94
|
+
const humanDecision = {
|
|
95
|
+
...response,
|
|
96
|
+
featureStatus: "planned"
|
|
97
|
+
};
|
|
98
|
+
await req.onRequireHuman(humanDecision);
|
|
99
|
+
}
|
|
100
|
+
return response;
|
|
101
|
+
},
|
|
102
|
+
async authorize(req) {
|
|
103
|
+
return request("/v1/authorize", "POST", {
|
|
104
|
+
decision_token: req.decisionToken,
|
|
105
|
+
tool_name: req.toolName,
|
|
106
|
+
args_hash: req.argsHash
|
|
107
|
+
});
|
|
108
|
+
},
|
|
109
|
+
async audit(req) {
|
|
110
|
+
return request("/v1/audit", "POST", {
|
|
111
|
+
run_id: req.runId,
|
|
112
|
+
action_id: req.actionId,
|
|
113
|
+
limit: req.limit || 50
|
|
114
|
+
});
|
|
115
|
+
},
|
|
116
|
+
async status() {
|
|
117
|
+
return request("/v1/status", "GET");
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
async function computeArgsHash(args) {
|
|
122
|
+
const canonical = JSON.stringify(args, Object.keys(args).sort());
|
|
123
|
+
const encoder = new TextEncoder();
|
|
124
|
+
const data = encoder.encode(canonical);
|
|
125
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
126
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
127
|
+
return "sha256:" + hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
128
|
+
}
|
|
129
|
+
function isTokenExpired(token) {
|
|
130
|
+
try {
|
|
131
|
+
const parts = token.split(".");
|
|
132
|
+
if (parts.length !== 3) return true;
|
|
133
|
+
const payload = JSON.parse(atob(parts[1]));
|
|
134
|
+
return payload.exp * 1e3 < Date.now();
|
|
135
|
+
} catch {
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
var index_default = createClient;
|
|
140
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
141
|
+
0 && (module.exports = {
|
|
142
|
+
CreedError,
|
|
143
|
+
computeArgsHash,
|
|
144
|
+
createClient,
|
|
145
|
+
isTokenExpired
|
|
146
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
var CreedError = class extends Error {
|
|
3
|
+
constructor(message, code, statusCode) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.code = code;
|
|
6
|
+
this.statusCode = statusCode;
|
|
7
|
+
this.name = "CreedError";
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
function createClient(options) {
|
|
11
|
+
const {
|
|
12
|
+
apiKey,
|
|
13
|
+
baseUrl = "https://api.creed.space",
|
|
14
|
+
fetch: customFetch = fetch,
|
|
15
|
+
timeoutMs = 3e4
|
|
16
|
+
} = options;
|
|
17
|
+
if (!apiKey) {
|
|
18
|
+
throw new CreedError("API key is required", "MISSING_API_KEY");
|
|
19
|
+
}
|
|
20
|
+
async function request(endpoint, method, body) {
|
|
21
|
+
const controller = new AbortController();
|
|
22
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
23
|
+
try {
|
|
24
|
+
const response = await customFetch(`${baseUrl}${endpoint}`, {
|
|
25
|
+
method,
|
|
26
|
+
headers: {
|
|
27
|
+
"Content-Type": "application/json",
|
|
28
|
+
Authorization: `Bearer ${apiKey}`,
|
|
29
|
+
"X-Creed-SDK": "typescript/1.0.0"
|
|
30
|
+
},
|
|
31
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
32
|
+
signal: controller.signal
|
|
33
|
+
});
|
|
34
|
+
if (!response.ok) {
|
|
35
|
+
const errorBody = await response.text();
|
|
36
|
+
throw new CreedError(
|
|
37
|
+
errorBody || `Request failed with status ${response.status}`,
|
|
38
|
+
"REQUEST_FAILED",
|
|
39
|
+
response.status
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
return response.json();
|
|
43
|
+
} catch (error) {
|
|
44
|
+
if (error instanceof CreedError) throw error;
|
|
45
|
+
if (error.name === "AbortError") {
|
|
46
|
+
throw new CreedError("Request timed out", "TIMEOUT");
|
|
47
|
+
}
|
|
48
|
+
throw new CreedError(error.message, "NETWORK_ERROR");
|
|
49
|
+
} finally {
|
|
50
|
+
clearTimeout(timeoutId);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
async decide(req) {
|
|
55
|
+
const response = await request("/v1/decide", "POST", {
|
|
56
|
+
tool_name: req.toolName,
|
|
57
|
+
arguments: req.arguments,
|
|
58
|
+
constitution_id: req.constitutionId || "default",
|
|
59
|
+
context: req.context || {}
|
|
60
|
+
});
|
|
61
|
+
if (response.decision === "ALLOW" && req.onAllow) {
|
|
62
|
+
await req.onAllow(response);
|
|
63
|
+
} else if (response.decision === "DENY" && req.onDeny) {
|
|
64
|
+
await req.onDeny(response);
|
|
65
|
+
} else if (response.decision === "REQUIRE_HUMAN" && req.onRequireHuman) {
|
|
66
|
+
const humanDecision = {
|
|
67
|
+
...response,
|
|
68
|
+
featureStatus: "planned"
|
|
69
|
+
};
|
|
70
|
+
await req.onRequireHuman(humanDecision);
|
|
71
|
+
}
|
|
72
|
+
return response;
|
|
73
|
+
},
|
|
74
|
+
async authorize(req) {
|
|
75
|
+
return request("/v1/authorize", "POST", {
|
|
76
|
+
decision_token: req.decisionToken,
|
|
77
|
+
tool_name: req.toolName,
|
|
78
|
+
args_hash: req.argsHash
|
|
79
|
+
});
|
|
80
|
+
},
|
|
81
|
+
async audit(req) {
|
|
82
|
+
return request("/v1/audit", "POST", {
|
|
83
|
+
run_id: req.runId,
|
|
84
|
+
action_id: req.actionId,
|
|
85
|
+
limit: req.limit || 50
|
|
86
|
+
});
|
|
87
|
+
},
|
|
88
|
+
async status() {
|
|
89
|
+
return request("/v1/status", "GET");
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
async function computeArgsHash(args) {
|
|
94
|
+
const canonical = JSON.stringify(args, Object.keys(args).sort());
|
|
95
|
+
const encoder = new TextEncoder();
|
|
96
|
+
const data = encoder.encode(canonical);
|
|
97
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
98
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
99
|
+
return "sha256:" + hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
100
|
+
}
|
|
101
|
+
function isTokenExpired(token) {
|
|
102
|
+
try {
|
|
103
|
+
const parts = token.split(".");
|
|
104
|
+
if (parts.length !== 3) return true;
|
|
105
|
+
const payload = JSON.parse(atob(parts[1]));
|
|
106
|
+
return payload.exp * 1e3 < Date.now();
|
|
107
|
+
} catch {
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
var index_default = createClient;
|
|
112
|
+
export {
|
|
113
|
+
CreedError,
|
|
114
|
+
computeArgsHash,
|
|
115
|
+
createClient,
|
|
116
|
+
index_default as default,
|
|
117
|
+
isTokenExpired
|
|
118
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@creedspace/sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Creed Space SDK - Governance infrastructure for AI agents",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"src"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
21
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
22
|
+
"lint": "eslint src --ext .ts",
|
|
23
|
+
"typecheck": "tsc --noEmit",
|
|
24
|
+
"test": "vitest run",
|
|
25
|
+
"test:watch": "vitest"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"creed",
|
|
29
|
+
"ai",
|
|
30
|
+
"agents",
|
|
31
|
+
"governance",
|
|
32
|
+
"safety",
|
|
33
|
+
"constitutional-ai",
|
|
34
|
+
"tool-calling"
|
|
35
|
+
],
|
|
36
|
+
"author": "Creed Space <support@creed.space>",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "https://github.com/creed-space/sdk-typescript"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://creed.space/docs/sdk",
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "^20.0.0",
|
|
45
|
+
"tsup": "^8.0.0",
|
|
46
|
+
"typescript": "^5.3.0",
|
|
47
|
+
"vitest": "^1.0.0",
|
|
48
|
+
"eslint": "^8.0.0",
|
|
49
|
+
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
|
50
|
+
"@typescript-eslint/parser": "^6.0.0"
|
|
51
|
+
},
|
|
52
|
+
"engines": {
|
|
53
|
+
"node": ">=18.0.0"
|
|
54
|
+
}
|
|
55
|
+
}
|