@peers-app/peers-sdk 0.16.5 → 0.17.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/dist/contracts/__tests__/builder.test.d.ts +1 -0
- package/dist/contracts/__tests__/builder.test.js +426 -0
- package/dist/contracts/__tests__/extract.test.d.ts +1 -0
- package/dist/contracts/__tests__/extract.test.js +145 -0
- package/dist/contracts/__tests__/integration.test.d.ts +1 -0
- package/dist/contracts/__tests__/integration.test.js +348 -0
- package/dist/contracts/__tests__/registry.test.d.ts +1 -0
- package/dist/contracts/__tests__/registry.test.js +324 -0
- package/dist/contracts/__tests__/validate.test.d.ts +1 -0
- package/dist/contracts/__tests__/validate.test.js +699 -0
- package/dist/contracts/builder.d.ts +102 -0
- package/dist/contracts/builder.js +216 -0
- package/dist/contracts/contract-providers.table.d.ts +40 -0
- package/dist/contracts/contract-providers.table.js +41 -0
- package/dist/contracts/contracts.table.d.ts +44 -0
- package/dist/contracts/contracts.table.js +44 -0
- package/dist/contracts/extract.d.ts +46 -0
- package/dist/contracts/extract.js +51 -0
- package/dist/contracts/index.d.ts +9 -0
- package/dist/contracts/index.js +31 -0
- package/dist/contracts/persistent-registry.d.ts +32 -0
- package/dist/contracts/persistent-registry.js +138 -0
- package/dist/contracts/registry.d.ts +58 -0
- package/dist/contracts/registry.js +155 -0
- package/dist/contracts/types.d.ts +108 -0
- package/dist/contracts/types.js +10 -0
- package/dist/contracts/validate.d.ts +24 -0
- package/dist/contracts/validate.js +274 -0
- package/dist/data/assistants.d.ts +5 -0
- package/dist/data/assistants.js +1 -0
- package/dist/data/package-versions.d.ts +2 -2
- package/dist/data/persistent-vars.d.ts +3 -0
- package/dist/data/persistent-vars.js +3 -0
- package/dist/data/tools.d.ts +5 -2
- package/dist/data/tools.js +1 -1
- package/dist/data/workflows.d.ts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/package-loader/contract-package-loader.d.ts +23 -0
- package/dist/package-loader/contract-package-loader.js +65 -0
- package/dist/package-loader/index.d.ts +1 -0
- package/dist/package-loader/index.js +1 -0
- package/dist/package-loader/package-loader.d.ts +11 -0
- package/dist/package-loader/package-loader.js +59 -8
- package/dist/rpc-types.d.ts +7 -0
- package/dist/rpc-types.js +4 -0
- package/dist/types/workflow.d.ts +3 -0
- package/dist/types/workflow.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateProviderSatisfiesContract = validateProviderSatisfiesContract;
|
|
4
|
+
exports.validateImmutability = validateImmutability;
|
|
5
|
+
exports.validateAlsoImplements = validateAlsoImplements;
|
|
6
|
+
const types_1 = require("./types");
|
|
7
|
+
function ok() {
|
|
8
|
+
return { valid: true, errors: [] };
|
|
9
|
+
}
|
|
10
|
+
function fail(errors) {
|
|
11
|
+
return { valid: false, errors };
|
|
12
|
+
}
|
|
13
|
+
function merge(results) {
|
|
14
|
+
const errors = results.flatMap((r) => r.errors);
|
|
15
|
+
return { valid: errors.length === 0, errors };
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Check whether `implField` satisfies the contract's `contractField`.
|
|
19
|
+
* - Types must match exactly.
|
|
20
|
+
* - If the contract field is required, the implementation must also be required.
|
|
21
|
+
* - `isArray` must match.
|
|
22
|
+
*/
|
|
23
|
+
function isFieldCompatible(contractField, implField) {
|
|
24
|
+
if (contractField.type !== implField.type) {
|
|
25
|
+
return `type mismatch: contract requires '${contractField.type}', implementation has '${implField.type}'`;
|
|
26
|
+
}
|
|
27
|
+
if (contractField.isArray && !implField.isArray) {
|
|
28
|
+
return "contract requires array, implementation is not an array";
|
|
29
|
+
}
|
|
30
|
+
if (!contractField.isArray && implField.isArray) {
|
|
31
|
+
return "contract requires scalar, implementation is an array";
|
|
32
|
+
}
|
|
33
|
+
if (!contractField.optional && implField.optional) {
|
|
34
|
+
return "contract requires a required field, implementation marks it optional";
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
function validateTableFields(contractTable, implTable) {
|
|
39
|
+
const errors = [];
|
|
40
|
+
const implFieldMap = new Map(implTable.fields.map((f) => [f.name, f]));
|
|
41
|
+
for (const contractField of contractTable.fields) {
|
|
42
|
+
const implField = implFieldMap.get(contractField.name);
|
|
43
|
+
if (!implField) {
|
|
44
|
+
if (!contractField.optional) {
|
|
45
|
+
errors.push({
|
|
46
|
+
kind: "field",
|
|
47
|
+
name: `${contractTable.name}.${contractField.name}`,
|
|
48
|
+
message: `Required field '${contractField.name}' missing from implementation table '${implTable.name}'`,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const compat = isFieldCompatible(contractField, implField);
|
|
54
|
+
if (compat) {
|
|
55
|
+
errors.push({
|
|
56
|
+
kind: "field",
|
|
57
|
+
name: `${contractTable.name}.${contractField.name}`,
|
|
58
|
+
message: `Field '${contractField.name}' in table '${implTable.name}': ${compat}`,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Extra fields in the implementation are allowed only if optional
|
|
63
|
+
for (const implField of implTable.fields) {
|
|
64
|
+
const inContract = contractTable.fields.some((f) => f.name === implField.name);
|
|
65
|
+
if (!inContract && !implField.optional) {
|
|
66
|
+
errors.push({
|
|
67
|
+
kind: "field",
|
|
68
|
+
name: `${implTable.name}.${implField.name}`,
|
|
69
|
+
message: `Implementation table '${implTable.name}' has extra required field '${implField.name}' not in contract (must be optional)`,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return errors;
|
|
74
|
+
}
|
|
75
|
+
function validateToolFields(contractTool, implTool, direction) {
|
|
76
|
+
const errors = [];
|
|
77
|
+
const contractFields = direction === "input" ? contractTool.inputFields : contractTool.outputFields;
|
|
78
|
+
const implFields = direction === "input" ? implTool.inputFields : implTool.outputFields;
|
|
79
|
+
const implFieldMap = new Map(implFields.map((f) => [f.name, f]));
|
|
80
|
+
for (const contractField of contractFields) {
|
|
81
|
+
const implField = implFieldMap.get(contractField.name);
|
|
82
|
+
if (!implField) {
|
|
83
|
+
if (!contractField.optional) {
|
|
84
|
+
errors.push({
|
|
85
|
+
kind: "field",
|
|
86
|
+
name: `${contractTool.name}.${direction}.${contractField.name}`,
|
|
87
|
+
message: `Required ${direction} field '${contractField.name}' missing from tool '${implTool.name}'`,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
const compat = isFieldCompatible(contractField, implField);
|
|
93
|
+
if (compat) {
|
|
94
|
+
errors.push({
|
|
95
|
+
kind: "field",
|
|
96
|
+
name: `${contractTool.name}.${direction}.${contractField.name}`,
|
|
97
|
+
message: `Field '${contractField.name}' in tool '${implTool.name}' ${direction}: ${compat}`,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// For inputs: extra optional fields in the implementation are OK (the impl accepts more)
|
|
102
|
+
// For outputs: extra fields in the implementation are OK (the impl returns more)
|
|
103
|
+
if (direction === "input") {
|
|
104
|
+
for (const implField of implFields) {
|
|
105
|
+
const inContract = contractFields.some((f) => f.name === implField.name);
|
|
106
|
+
if (!inContract && !implField.optional) {
|
|
107
|
+
errors.push({
|
|
108
|
+
kind: "field",
|
|
109
|
+
name: `${implTool.name}.${direction}.${implField.name}`,
|
|
110
|
+
message: `Implementation tool '${implTool.name}' has extra required input field '${implField.name}' not in contract (must be optional)`,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return errors;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Validate that an implementation contract satisfies a target contract shape.
|
|
119
|
+
* The implementation must be a superset: all contract tables, tools, and
|
|
120
|
+
* observables must be present with compatible shapes.
|
|
121
|
+
*/
|
|
122
|
+
function validateProviderSatisfiesContract(impl, contract) {
|
|
123
|
+
const errors = [];
|
|
124
|
+
// Tables
|
|
125
|
+
const implTableMap = new Map(impl.tables.map((t) => [t.name, t]));
|
|
126
|
+
for (const contractTable of contract.tables) {
|
|
127
|
+
const implTable = implTableMap.get(contractTable.name);
|
|
128
|
+
if (!implTable) {
|
|
129
|
+
errors.push({
|
|
130
|
+
kind: "table",
|
|
131
|
+
name: contractTable.name,
|
|
132
|
+
message: `Table '${contractTable.name}' required by contract but not provided by implementation`,
|
|
133
|
+
});
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (implTable.primaryKeyName !== contractTable.primaryKeyName) {
|
|
137
|
+
errors.push({
|
|
138
|
+
kind: "table",
|
|
139
|
+
name: contractTable.name,
|
|
140
|
+
message: `Table '${contractTable.name}': primary key mismatch — contract expects '${contractTable.primaryKeyName}', implementation has '${implTable.primaryKeyName}'`,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
errors.push(...validateTableFields(contractTable, implTable));
|
|
144
|
+
}
|
|
145
|
+
// Tools
|
|
146
|
+
const implToolMap = new Map(impl.tools.map((t) => [t.name, t]));
|
|
147
|
+
for (const contractTool of contract.tools) {
|
|
148
|
+
const implTool = implToolMap.get(contractTool.name);
|
|
149
|
+
if (!implTool) {
|
|
150
|
+
errors.push({
|
|
151
|
+
kind: "tool",
|
|
152
|
+
name: contractTool.name,
|
|
153
|
+
message: `Tool '${contractTool.name}' required by contract but not provided by implementation`,
|
|
154
|
+
});
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
errors.push(...validateToolFields(contractTool, implTool, "input"));
|
|
158
|
+
errors.push(...validateToolFields(contractTool, implTool, "output"));
|
|
159
|
+
}
|
|
160
|
+
// Observables
|
|
161
|
+
const implObsMap = new Map(impl.observables.map((o) => [o.name, o]));
|
|
162
|
+
for (const contractObs of contract.observables) {
|
|
163
|
+
const implObs = implObsMap.get(contractObs.name);
|
|
164
|
+
if (!implObs) {
|
|
165
|
+
errors.push({
|
|
166
|
+
kind: "observable",
|
|
167
|
+
name: contractObs.name,
|
|
168
|
+
message: `Observable '${contractObs.name}' required by contract but not provided by implementation`,
|
|
169
|
+
});
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
if (contractObs.valueType !== implObs.valueType) {
|
|
173
|
+
errors.push({
|
|
174
|
+
kind: "observable",
|
|
175
|
+
name: contractObs.name,
|
|
176
|
+
message: `Observable '${contractObs.name}': type mismatch — contract expects '${contractObs.valueType}', implementation has '${implObs.valueType}'`,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
if (contractObs.writable && !implObs.writable) {
|
|
180
|
+
errors.push({
|
|
181
|
+
kind: "observable",
|
|
182
|
+
name: contractObs.name,
|
|
183
|
+
message: `Observable '${contractObs.name}' must be writable per contract, but implementation is read-only`,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return errors.length === 0 ? ok() : fail(errors);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Validate that a frozen (stable) contract definition has not been modified.
|
|
191
|
+
* If the existing definition has no `devTag` it is frozen; the incoming
|
|
192
|
+
* definition must be structurally identical and also stable.
|
|
193
|
+
* Dev contracts (`devTag: "dev"`) may change freely but cannot be registered
|
|
194
|
+
* once a stable version exists for that contract+version.
|
|
195
|
+
*/
|
|
196
|
+
function validateImmutability(existing, incoming) {
|
|
197
|
+
if (existing.devTag === "dev") {
|
|
198
|
+
return ok();
|
|
199
|
+
}
|
|
200
|
+
// Existing is stable/frozen — reject any attempt to register a dev version
|
|
201
|
+
if (incoming.devTag === "dev") {
|
|
202
|
+
return fail([
|
|
203
|
+
{
|
|
204
|
+
kind: "contract",
|
|
205
|
+
name: (0, types_1.contractKey)(existing.contractId, existing.version),
|
|
206
|
+
message: `Cannot register a dev version for stable contract ${existing.name} v${existing.version} — contract is already frozen`,
|
|
207
|
+
},
|
|
208
|
+
]);
|
|
209
|
+
}
|
|
210
|
+
// Deep-compare the shapes. We serialize to JSON for a simple structural comparison.
|
|
211
|
+
const existingShape = JSON.stringify({
|
|
212
|
+
tables: existing.tables,
|
|
213
|
+
tools: existing.tools,
|
|
214
|
+
observables: existing.observables,
|
|
215
|
+
});
|
|
216
|
+
const incomingShape = JSON.stringify({
|
|
217
|
+
tables: incoming.tables,
|
|
218
|
+
tools: incoming.tools,
|
|
219
|
+
observables: incoming.observables,
|
|
220
|
+
});
|
|
221
|
+
if (existingShape !== incomingShape) {
|
|
222
|
+
return fail([
|
|
223
|
+
{
|
|
224
|
+
kind: "contract",
|
|
225
|
+
name: (0, types_1.contractKey)(existing.contractId, existing.version),
|
|
226
|
+
message: `Stable contract ${existing.name} v${existing.version} is frozen and cannot be modified`,
|
|
227
|
+
},
|
|
228
|
+
]);
|
|
229
|
+
}
|
|
230
|
+
return ok();
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Validate that an implementation satisfies all contracts referenced by its
|
|
234
|
+
* `alsoImplements` declarations.
|
|
235
|
+
*
|
|
236
|
+
* @param impl The implementation's extracted contract definition.
|
|
237
|
+
* @param declarations The `alsoImplements` declarations for this contract.
|
|
238
|
+
* @param getContract Callback to look up an existing contract definition.
|
|
239
|
+
*/
|
|
240
|
+
function validateAlsoImplements(impl, declarations, getContract) {
|
|
241
|
+
const results = [];
|
|
242
|
+
for (const decl of declarations) {
|
|
243
|
+
const versions = [];
|
|
244
|
+
if (typeof decl.version === "number") {
|
|
245
|
+
versions.push(decl.version);
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
for (let v = decl.version.from; v <= decl.version.to; v++) {
|
|
249
|
+
versions.push(v);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
for (const ver of versions) {
|
|
253
|
+
const target = getContract(decl.contractId, ver);
|
|
254
|
+
if (!target) {
|
|
255
|
+
results.push(fail([
|
|
256
|
+
{
|
|
257
|
+
kind: "contract",
|
|
258
|
+
name: (0, types_1.contractKey)(decl.contractId, ver),
|
|
259
|
+
message: `alsoImplements references contract ${decl.contractId} v${ver}, but that contract was not found`,
|
|
260
|
+
},
|
|
261
|
+
]));
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
const result = validateProviderSatisfiesContract(impl, target);
|
|
265
|
+
if (!result.valid) {
|
|
266
|
+
for (const error of result.errors) {
|
|
267
|
+
error.message = `[alsoImplements ${decl.contractId} v${ver}] ${error.message}`;
|
|
268
|
+
}
|
|
269
|
+
results.push(result);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return merge(results);
|
|
274
|
+
}
|
|
@@ -15,6 +15,7 @@ export declare const assistantSchema: z.ZodObject<{
|
|
|
15
15
|
assistantRunnerConfig: z.ZodDefault<z.ZodObject<{}, "strip", z.ZodAny, z.objectOutputType<{}, z.ZodAny, "strip">, z.objectInputType<{}, z.ZodAny, "strip">>>;
|
|
16
16
|
toolsToInclude: z.ZodDefault<z.ZodString>;
|
|
17
17
|
toolInclusionStrategy: z.ZodDefault<z.ZodNativeEnum<typeof ToolInclusionStrategy>>;
|
|
18
|
+
packageId: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
18
19
|
}, "strip", z.ZodTypeAny, {
|
|
19
20
|
name: string;
|
|
20
21
|
createdAt: Date;
|
|
@@ -26,11 +27,13 @@ export declare const assistantSchema: z.ZodObject<{
|
|
|
26
27
|
toolsToInclude: string;
|
|
27
28
|
toolInclusionStrategy: ToolInclusionStrategy;
|
|
28
29
|
description?: string | undefined;
|
|
30
|
+
packageId?: string | undefined;
|
|
29
31
|
updatedAt?: Date | undefined;
|
|
30
32
|
}, {
|
|
31
33
|
name: string;
|
|
32
34
|
assistantId: string;
|
|
33
35
|
description?: string | undefined;
|
|
36
|
+
packageId?: string | undefined;
|
|
34
37
|
createdAt?: Date | undefined;
|
|
35
38
|
updatedAt?: Date | undefined;
|
|
36
39
|
assistantRunnerToolId?: string | undefined;
|
|
@@ -50,6 +53,7 @@ export declare function Assistants(dataContext?: DataContext): import("./orm").T
|
|
|
50
53
|
toolsToInclude: string;
|
|
51
54
|
toolInclusionStrategy: ToolInclusionStrategy;
|
|
52
55
|
description?: string | undefined;
|
|
56
|
+
packageId?: string | undefined;
|
|
53
57
|
updatedAt?: Date | undefined;
|
|
54
58
|
}>;
|
|
55
59
|
/**
|
|
@@ -73,6 +77,7 @@ export declare const getPrimaryAssistant: (dataContext?: DataContext) => Promise
|
|
|
73
77
|
toolsToInclude: string;
|
|
74
78
|
toolInclusionStrategy: ToolInclusionStrategy;
|
|
75
79
|
description?: string | undefined;
|
|
80
|
+
packageId?: string | undefined;
|
|
76
81
|
updatedAt?: Date | undefined;
|
|
77
82
|
}>;
|
|
78
83
|
export declare function getAllAssistantIdsMentioned(message: string): Promise<string[]>;
|
package/dist/data/assistants.js
CHANGED
|
@@ -46,6 +46,7 @@ exports.assistantSchema = zod_1.z.object({
|
|
|
46
46
|
"- **Linked** - `Fixed` plus tools linked in the message or chat history of the assistant's current conversation.",
|
|
47
47
|
"- **Relevant** - `Linked` plus tools matching the context of the conversation determined via vector search (embeddings) of the tools descriptions.",
|
|
48
48
|
].join("\n")),
|
|
49
|
+
packageId: zod_types_1.zodPeerId.optional().describe("The package that installed this assistant, if any"),
|
|
49
50
|
});
|
|
50
51
|
const metaData = {
|
|
51
52
|
name: "Assistants",
|
|
@@ -36,8 +36,8 @@ declare const schema: z.ZodObject<{
|
|
|
36
36
|
}, "strip", z.ZodTypeAny, {
|
|
37
37
|
version: string;
|
|
38
38
|
signature: string;
|
|
39
|
-
packageVersionId: string;
|
|
40
39
|
packageId: string;
|
|
40
|
+
packageVersionId: string;
|
|
41
41
|
packageVersionHash: string;
|
|
42
42
|
packageBundleFileId: string;
|
|
43
43
|
packageBundleFileHash: string;
|
|
@@ -57,8 +57,8 @@ declare const schema: z.ZodObject<{
|
|
|
57
57
|
}, {
|
|
58
58
|
version: string;
|
|
59
59
|
signature: string;
|
|
60
|
-
packageVersionId: string;
|
|
61
60
|
packageId: string;
|
|
61
|
+
packageVersionId: string;
|
|
62
62
|
packageVersionHash: string;
|
|
63
63
|
packageBundleFileId: string;
|
|
64
64
|
packageBundleFileHash: string;
|
|
@@ -26,6 +26,7 @@ declare const schema: z.ZodObject<{
|
|
|
26
26
|
userCreated: z.ZodOptional<z.ZodBoolean>;
|
|
27
27
|
isSecret: z.ZodOptional<z.ZodBoolean>;
|
|
28
28
|
modifiedAt: z.ZodOptional<z.ZodNumber>;
|
|
29
|
+
packageId: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
29
30
|
}, "strip", z.ZodTypeAny, {
|
|
30
31
|
name: string;
|
|
31
32
|
value: {
|
|
@@ -37,6 +38,7 @@ declare const schema: z.ZodObject<{
|
|
|
37
38
|
userCreated?: boolean | undefined;
|
|
38
39
|
isSecret?: boolean | undefined;
|
|
39
40
|
modifiedAt?: number | undefined;
|
|
41
|
+
packageId?: string | undefined;
|
|
40
42
|
}, {
|
|
41
43
|
name: string;
|
|
42
44
|
value: {
|
|
@@ -48,6 +50,7 @@ declare const schema: z.ZodObject<{
|
|
|
48
50
|
userCreated?: boolean | undefined;
|
|
49
51
|
isSecret?: boolean | undefined;
|
|
50
52
|
modifiedAt?: number | undefined;
|
|
53
|
+
packageId?: string | undefined;
|
|
51
54
|
}>;
|
|
52
55
|
export declare const persistentVarsMetaData: ITableMetaData;
|
|
53
56
|
export type IPersistentVar = z.infer<typeof schema>;
|
|
@@ -40,6 +40,9 @@ const schema = zod_1.z.object({
|
|
|
40
40
|
.number()
|
|
41
41
|
.optional()
|
|
42
42
|
.describe("Timestamp of when this pvar was last modified (Date.now())"),
|
|
43
|
+
packageId: zod_types_1.zodPeerId
|
|
44
|
+
.optional()
|
|
45
|
+
.describe("The package that owns this persistent variable, if any"),
|
|
43
46
|
});
|
|
44
47
|
exports.persistentVarsMetaData = {
|
|
45
48
|
name: "PersistentVars",
|
package/dist/data/tools.d.ts
CHANGED
|
@@ -3,8 +3,7 @@ import type { DataContext } from "../context/data-context";
|
|
|
3
3
|
export declare enum IOSchemaType {
|
|
4
4
|
none = "none",
|
|
5
5
|
simple = "simple",
|
|
6
|
-
complex = "complex"
|
|
7
|
-
code = "code"
|
|
6
|
+
complex = "complex"
|
|
8
7
|
}
|
|
9
8
|
export declare const ioSchema: z.ZodObject<{
|
|
10
9
|
type: z.ZodNativeEnum<typeof IOSchemaType>;
|
|
@@ -215,6 +214,7 @@ export declare const toolSchema: z.ZodObject<{
|
|
|
215
214
|
code: z.ZodDefault<z.ZodString>;
|
|
216
215
|
codeRepository: z.ZodOptional<z.ZodString>;
|
|
217
216
|
isAssistantRunner: z.ZodOptional<z.ZodBoolean>;
|
|
217
|
+
packageId: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
218
218
|
}, "strip", z.ZodTypeAny, {
|
|
219
219
|
code: string;
|
|
220
220
|
name: string;
|
|
@@ -244,6 +244,7 @@ export declare const toolSchema: z.ZodObject<{
|
|
|
244
244
|
subType?: string | undefined;
|
|
245
245
|
}[];
|
|
246
246
|
};
|
|
247
|
+
packageId?: string | undefined;
|
|
247
248
|
detailedDescription?: string | undefined;
|
|
248
249
|
configSchema?: {
|
|
249
250
|
type: IOSchemaType;
|
|
@@ -288,6 +289,7 @@ export declare const toolSchema: z.ZodObject<{
|
|
|
288
289
|
}[] | undefined;
|
|
289
290
|
};
|
|
290
291
|
code?: string | undefined;
|
|
292
|
+
packageId?: string | undefined;
|
|
291
293
|
detailedDescription?: string | undefined;
|
|
292
294
|
configSchema?: {
|
|
293
295
|
type: IOSchemaType;
|
|
@@ -340,6 +342,7 @@ export declare function Tools(dataContext?: DataContext): import("./orm").Table<
|
|
|
340
342
|
subType?: string | undefined;
|
|
341
343
|
}[];
|
|
342
344
|
};
|
|
345
|
+
packageId?: string | undefined;
|
|
343
346
|
detailedDescription?: string | undefined;
|
|
344
347
|
configSchema?: {
|
|
345
348
|
type: IOSchemaType;
|
package/dist/data/tools.js
CHANGED
|
@@ -13,7 +13,6 @@ var IOSchemaType;
|
|
|
13
13
|
IOSchemaType["none"] = "none";
|
|
14
14
|
IOSchemaType["simple"] = "simple";
|
|
15
15
|
IOSchemaType["complex"] = "complex";
|
|
16
|
-
IOSchemaType["code"] = "code";
|
|
17
16
|
})(IOSchemaType || (exports.IOSchemaType = IOSchemaType = {}));
|
|
18
17
|
exports.ioSchema = zod_1.z.object({
|
|
19
18
|
type: zod_1.z.nativeEnum(IOSchemaType),
|
|
@@ -44,6 +43,7 @@ exports.toolSchema = zod_1.z.object({
|
|
|
44
43
|
.boolean()
|
|
45
44
|
.optional()
|
|
46
45
|
.describe("Whether this tool is a model that can be used to run an assistant"),
|
|
46
|
+
packageId: zod_types_1.zodPeerId.optional().describe("The package that installed this tool, if any"),
|
|
47
47
|
});
|
|
48
48
|
const metaData = {
|
|
49
49
|
name: "Tools",
|
package/dist/data/workflows.d.ts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -16,6 +16,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
exports.tools = exports.workflowLogSchema = exports.WorkflowLogs = exports.getLogger = exports.orm = exports.data = void 0;
|
|
18
18
|
__exportStar(require("./context"), exports);
|
|
19
|
+
__exportStar(require("./contracts"), exports);
|
|
19
20
|
__exportStar(require("./data"), exports);
|
|
20
21
|
exports.data = require("./data");
|
|
21
22
|
__exportStar(require("./data/orm"), exports);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { DataContext } from "../context/data-context";
|
|
2
|
+
import type { ContractRegistry } from "../contracts/registry";
|
|
3
|
+
import type { IPackageDefinitionResult } from "../contracts/types";
|
|
4
|
+
/**
|
|
5
|
+
* Installs a contract-based package into a DataContext.
|
|
6
|
+
*
|
|
7
|
+
* Handles packages that export an `IPackageDefinitionResult` from `definePackage()`.
|
|
8
|
+
* Registers contracts in the provided ContractRegistry, saves tools/assistants/workflows
|
|
9
|
+
* with the `packageId` from the definition set, and registers table definitions.
|
|
10
|
+
*/
|
|
11
|
+
export declare function installContractPackage(dataContext: DataContext, packageDefinition: IPackageDefinitionResult, opts?: {
|
|
12
|
+
registry?: ContractRegistry;
|
|
13
|
+
}): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Attempts to extract an `IPackageDefinitionResult` from a bundle's module exports.
|
|
16
|
+
* Returns undefined if the bundle doesn't export a contract-based package definition.
|
|
17
|
+
*/
|
|
18
|
+
export declare function extractPackageDefinition(bundleExports: Record<string, unknown>): IPackageDefinitionResult | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Determines whether a bundle exports a contract-based package definition,
|
|
21
|
+
* indicating it should be installed via the new contract-aware path.
|
|
22
|
+
*/
|
|
23
|
+
export declare function hasPackageDefinition(bundleExports: Record<string, unknown>): boolean;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.installContractPackage = installContractPackage;
|
|
4
|
+
exports.extractPackageDefinition = extractPackageDefinition;
|
|
5
|
+
exports.hasPackageDefinition = hasPackageDefinition;
|
|
6
|
+
const tools_1 = require("../data/tools");
|
|
7
|
+
const tools_2 = require("../tools");
|
|
8
|
+
/**
|
|
9
|
+
* Installs a contract-based package into a DataContext.
|
|
10
|
+
*
|
|
11
|
+
* Handles packages that export an `IPackageDefinitionResult` from `definePackage()`.
|
|
12
|
+
* Registers contracts in the provided ContractRegistry, saves tools/assistants/workflows
|
|
13
|
+
* with the `packageId` from the definition set, and registers table definitions.
|
|
14
|
+
*/
|
|
15
|
+
async function installContractPackage(dataContext, packageDefinition, opts) {
|
|
16
|
+
const { packageId } = packageDefinition;
|
|
17
|
+
const registry = opts?.registry;
|
|
18
|
+
// Register contracts in the in-memory registry
|
|
19
|
+
if (registry) {
|
|
20
|
+
for (const contract of packageDefinition.contracts) {
|
|
21
|
+
const key = `${contract.contractId}@${contract.version}`;
|
|
22
|
+
const alsoImpl = packageDefinition.alsoImplements.get(key) ?? [];
|
|
23
|
+
const result = registry.register(packageId, contract, alsoImpl);
|
|
24
|
+
if (!result.valid) {
|
|
25
|
+
console.error(`[ContractPackageLoader] Contract registration failed for ${contract.name}:`, result.errors);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// Install tool instances with packageId
|
|
30
|
+
for (const toolInstance of packageDefinition.toolInstances) {
|
|
31
|
+
(0, tools_2.registerTool)(toolInstance);
|
|
32
|
+
const toolWithPackageId = { ...toolInstance.tool, packageId };
|
|
33
|
+
await (0, tools_1.Tools)(dataContext).save(toolWithPackageId);
|
|
34
|
+
}
|
|
35
|
+
// Install table definitions
|
|
36
|
+
for (const tableDefinition of packageDefinition.tableDefinitions) {
|
|
37
|
+
dataContext.tableContainer.registerTableDefinition(tableDefinition, {
|
|
38
|
+
overwrite: true,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
// Install assistants with packageId
|
|
42
|
+
const { Assistants } = await Promise.resolve().then(() => require("../data/assistants"));
|
|
43
|
+
for (const assistant of packageDefinition.assistants) {
|
|
44
|
+
const assistantWithPackageId = { ...assistant, packageId };
|
|
45
|
+
await Assistants(dataContext).save(assistantWithPackageId);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Attempts to extract an `IPackageDefinitionResult` from a bundle's module exports.
|
|
50
|
+
* Returns undefined if the bundle doesn't export a contract-based package definition.
|
|
51
|
+
*/
|
|
52
|
+
function extractPackageDefinition(bundleExports) {
|
|
53
|
+
const def = bundleExports?.packageDefinition;
|
|
54
|
+
if (def && Array.isArray(def.contracts) && def.contracts.length > 0) {
|
|
55
|
+
return def;
|
|
56
|
+
}
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Determines whether a bundle exports a contract-based package definition,
|
|
61
|
+
* indicating it should be installed via the new contract-aware path.
|
|
62
|
+
*/
|
|
63
|
+
function hasPackageDefinition(bundleExports) {
|
|
64
|
+
return extractPackageDefinition(bundleExports) !== undefined;
|
|
65
|
+
}
|
|
@@ -14,4 +14,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./contract-package-loader"), exports);
|
|
17
18
|
__exportStar(require("./package-loader"), exports);
|
|
@@ -6,8 +6,12 @@ export declare class PackageLoader {
|
|
|
6
6
|
static PeersSDK: any;
|
|
7
7
|
static Zod: any;
|
|
8
8
|
private packageInstances;
|
|
9
|
+
/** Packages that were installed via the contract-based path (tools/assistants/tables already saved with packageId). */
|
|
10
|
+
private contractInstalledPackages;
|
|
9
11
|
require: (<T>(module: string) => T) | undefined;
|
|
10
12
|
constructor(dataContext: DataContext);
|
|
13
|
+
/** Returns true if a package was installed via the contract-based definePackage() path. */
|
|
14
|
+
isContractInstalled(packageId: string): boolean;
|
|
11
15
|
loadAllPackages(opts?: {
|
|
12
16
|
force?: boolean;
|
|
13
17
|
}): Promise<void>;
|
|
@@ -16,6 +20,13 @@ export declare class PackageLoader {
|
|
|
16
20
|
localPath?: string;
|
|
17
21
|
}): Promise<IPeersPackage | undefined>;
|
|
18
22
|
private _readLocalBundle;
|
|
23
|
+
/**
|
|
24
|
+
* Post-correction: if the package definition carries version/versionTag,
|
|
25
|
+
* update the active IPackageVersion record to match. This fixes cases where
|
|
26
|
+
* the PV record was created with stale or placeholder values (e.g. "0.0.1")
|
|
27
|
+
* before the bundle was evaluated.
|
|
28
|
+
*/
|
|
29
|
+
private correctPackageVersion;
|
|
19
30
|
private _evaluateBundle;
|
|
20
31
|
}
|
|
21
32
|
export declare function setDefaultRequire(require: <T>(module: string) => T): void;
|