@executor-js/sdk 0.0.1 → 0.0.2

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.
Files changed (96) hide show
  1. package/README.md +125 -107
  2. package/dist/blob.d.ts +48 -0
  3. package/dist/blob.d.ts.map +1 -0
  4. package/dist/blob.test.d.ts +2 -0
  5. package/dist/blob.test.d.ts.map +1 -0
  6. package/dist/chunk-6LMMN2GP.js +4396 -0
  7. package/dist/chunk-6LMMN2GP.js.map +1 -0
  8. package/dist/config.d.ts +14 -0
  9. package/dist/config.d.ts.map +1 -0
  10. package/dist/connections.d.ts +107 -0
  11. package/dist/connections.d.ts.map +1 -0
  12. package/dist/connections.test.d.ts +2 -0
  13. package/dist/connections.test.d.ts.map +1 -0
  14. package/dist/core-schema.d.ts +372 -0
  15. package/dist/core-schema.d.ts.map +1 -0
  16. package/dist/core.js +273 -57
  17. package/dist/core.js.map +1 -1
  18. package/dist/elicitation.d.ts +18 -34
  19. package/dist/elicitation.d.ts.map +1 -1
  20. package/dist/error-handling.test.d.ts +2 -0
  21. package/dist/error-handling.test.d.ts.map +1 -0
  22. package/dist/errors.d.ts +95 -24
  23. package/dist/errors.d.ts.map +1 -1
  24. package/dist/executor.d.ts +107 -48
  25. package/dist/executor.d.ts.map +1 -1
  26. package/dist/executor.test.d.ts +2 -0
  27. package/dist/executor.test.d.ts.map +1 -0
  28. package/dist/ids.d.ts +6 -4
  29. package/dist/ids.d.ts.map +1 -1
  30. package/dist/index.d.ts +22 -16
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +80 -308
  33. package/dist/index.js.map +1 -1
  34. package/dist/oauth-discovery.d.ts +138 -0
  35. package/dist/oauth-discovery.d.ts.map +1 -0
  36. package/dist/oauth-discovery.test.d.ts +2 -0
  37. package/dist/oauth-discovery.test.d.ts.map +1 -0
  38. package/dist/oauth-helpers.d.ts +89 -0
  39. package/dist/oauth-helpers.d.ts.map +1 -0
  40. package/dist/oauth-helpers.test.d.ts +2 -0
  41. package/dist/oauth-helpers.test.d.ts.map +1 -0
  42. package/dist/oauth-popup-types.d.ts +14 -0
  43. package/dist/oauth-popup-types.d.ts.map +1 -0
  44. package/dist/oauth-service.d.ts +33 -0
  45. package/dist/oauth-service.d.ts.map +1 -0
  46. package/dist/oauth.d.ts +275 -0
  47. package/dist/oauth.d.ts.map +1 -0
  48. package/dist/plugin.d.ts +261 -27
  49. package/dist/plugin.d.ts.map +1 -1
  50. package/dist/policies.d.ts +56 -64
  51. package/dist/policies.d.ts.map +1 -1
  52. package/dist/policies.test.d.ts +2 -0
  53. package/dist/policies.test.d.ts.map +1 -0
  54. package/dist/promise-executor.d.ts +26 -128
  55. package/dist/promise-executor.d.ts.map +1 -1
  56. package/dist/promise.d.ts +12 -6
  57. package/dist/promise.d.ts.map +1 -1
  58. package/dist/promise.test.d.ts +2 -0
  59. package/dist/promise.test.d.ts.map +1 -0
  60. package/dist/schema-types.d.ts +6 -5
  61. package/dist/schema-types.d.ts.map +1 -1
  62. package/dist/scope.d.ts +5 -15
  63. package/dist/scope.d.ts.map +1 -1
  64. package/dist/scoped-adapter.d.ts +13 -0
  65. package/dist/scoped-adapter.d.ts.map +1 -0
  66. package/dist/scoped-adapter.test.d.ts +2 -0
  67. package/dist/scoped-adapter.test.d.ts.map +1 -0
  68. package/dist/secret-backed-value.d.ts +27 -0
  69. package/dist/secret-backed-value.d.ts.map +1 -0
  70. package/dist/secrets.d.ts +52 -106
  71. package/dist/secrets.d.ts.map +1 -1
  72. package/dist/testing.d.ts +5 -3
  73. package/dist/testing.d.ts.map +1 -1
  74. package/dist/types.d.ts +84 -0
  75. package/dist/types.d.ts.map +1 -0
  76. package/package.json +7 -4
  77. package/dist/chunk-D7CT3UMO.js +0 -1386
  78. package/dist/chunk-D7CT3UMO.js.map +0 -1
  79. package/dist/in-memory/policy-engine.d.ts +0 -10
  80. package/dist/in-memory/policy-engine.d.ts.map +0 -1
  81. package/dist/in-memory/secret-store.d.ts +0 -16
  82. package/dist/in-memory/secret-store.d.ts.map +0 -1
  83. package/dist/in-memory/tool-registry.d.ts +0 -35
  84. package/dist/in-memory/tool-registry.d.ts.map +0 -1
  85. package/dist/index.test.d.ts +0 -2
  86. package/dist/index.test.d.ts.map +0 -1
  87. package/dist/plugin-kv.d.ts +0 -48
  88. package/dist/plugin-kv.d.ts.map +0 -1
  89. package/dist/plugins/in-memory-tools.d.ts +0 -42
  90. package/dist/plugins/in-memory-tools.d.ts.map +0 -1
  91. package/dist/runtime-tools.d.ts +0 -41
  92. package/dist/runtime-tools.d.ts.map +0 -1
  93. package/dist/sources.d.ts +0 -130
  94. package/dist/sources.d.ts.map +0 -1
  95. package/dist/tools.d.ts +0 -219
  96. package/dist/tools.d.ts.map +0 -1
@@ -1,1386 +0,0 @@
1
- // src/ids.ts
2
- import { Schema } from "effect";
3
- var ScopeId = Schema.String.pipe(Schema.brand("ScopeId"));
4
- var ToolId = Schema.String.pipe(Schema.brand("ToolId"));
5
- var SecretId = Schema.String.pipe(Schema.brand("SecretId"));
6
- var PolicyId = Schema.String.pipe(Schema.brand("PolicyId"));
7
-
8
- // src/errors.ts
9
- import { Data, Schema as Schema2 } from "effect";
10
- var ToolNotFoundError = class extends Schema2.TaggedError()(
11
- "ToolNotFoundError",
12
- { toolId: ToolId }
13
- ) {
14
- };
15
- var ToolInvocationError = class extends Data.TaggedError("ToolInvocationError") {
16
- };
17
- var SecretNotFoundError = class extends Schema2.TaggedError()(
18
- "SecretNotFoundError",
19
- { secretId: SecretId }
20
- ) {
21
- };
22
- var SecretResolutionError = class extends Schema2.TaggedError()(
23
- "SecretResolutionError",
24
- {
25
- secretId: SecretId,
26
- message: Schema2.String
27
- }
28
- ) {
29
- };
30
- var PolicyDeniedError = class extends Schema2.TaggedError()(
31
- "PolicyDeniedError",
32
- {
33
- policyId: PolicyId,
34
- toolId: ToolId,
35
- reason: Schema2.String
36
- }
37
- ) {
38
- };
39
-
40
- // src/tools.ts
41
- import { Context, Schema as Schema3 } from "effect";
42
- var ToolAnnotations = class extends Schema3.Class("ToolAnnotations")({
43
- /** Whether this tool requires user approval before execution */
44
- requiresApproval: Schema3.optional(Schema3.Boolean),
45
- /** Human-readable description shown in the approval prompt */
46
- approvalDescription: Schema3.optional(Schema3.String)
47
- }) {
48
- };
49
- var ToolMetadata = class extends Schema3.Class("ToolMetadata")({
50
- id: ToolId,
51
- pluginKey: Schema3.String,
52
- /** Source this tool belongs to (namespace identifier) */
53
- sourceId: Schema3.String,
54
- name: Schema3.String,
55
- description: Schema3.optional(Schema3.String),
56
- /** Whether this tool may request elicitation during invocation */
57
- mayElicit: Schema3.optional(Schema3.Boolean)
58
- }) {
59
- };
60
- var ToolSchema = class extends Schema3.Class("ToolSchema")({
61
- id: ToolId,
62
- inputTypeScript: Schema3.optional(Schema3.String),
63
- outputTypeScript: Schema3.optional(Schema3.String),
64
- typeScriptDefinitions: Schema3.optional(
65
- Schema3.Record({ key: Schema3.String, value: Schema3.String })
66
- ),
67
- inputSchema: Schema3.optional(Schema3.Unknown),
68
- outputSchema: Schema3.optional(Schema3.Unknown)
69
- }) {
70
- };
71
- var ToolInvocationResult = class extends Schema3.Class(
72
- "ToolInvocationResult"
73
- )({
74
- data: Schema3.Unknown,
75
- error: Schema3.NullOr(Schema3.Unknown),
76
- status: Schema3.optional(Schema3.Number)
77
- }) {
78
- };
79
- var ToolListFilter = class extends Schema3.Class("ToolListFilter")({
80
- /** Filter to tools belonging to a specific source */
81
- sourceId: Schema3.optional(Schema3.String),
82
- query: Schema3.optional(Schema3.String)
83
- }) {
84
- };
85
- var ToolRegistry = class extends Context.Tag("@executor-js/sdk/ToolRegistry")() {
86
- };
87
- var ToolRegistration = class extends Schema3.Class("ToolRegistration")({
88
- id: ToolId,
89
- pluginKey: Schema3.String,
90
- /** Source this tool belongs to (namespace identifier) */
91
- sourceId: Schema3.String,
92
- name: Schema3.String,
93
- description: Schema3.optional(Schema3.String),
94
- mayElicit: Schema3.optional(Schema3.Boolean),
95
- inputSchema: Schema3.optional(Schema3.Unknown),
96
- outputSchema: Schema3.optional(Schema3.Unknown)
97
- }) {
98
- };
99
-
100
- // src/sources.ts
101
- import { Context as Context2, Effect as Effect2, Schema as Schema4 } from "effect";
102
- var Source = class extends Schema4.Class("Source")({
103
- /** Unique namespace identifier (e.g. "github_rest") */
104
- id: Schema4.String,
105
- /** Human-readable name */
106
- name: Schema4.String,
107
- /** Plugin kind that manages this source (e.g. "openapi", "mcp") */
108
- kind: Schema4.String,
109
- /** Optional upstream URL for this source — used to derive a favicon in the UI */
110
- url: Schema4.optional(Schema4.String),
111
- /** True when the source is provided by the running executor */
112
- runtime: Schema4.optional(Schema4.Boolean),
113
- /** Whether the source supports removal */
114
- canRemove: Schema4.optional(Schema4.Boolean),
115
- /** Whether the source supports refresh */
116
- canRefresh: Schema4.optional(Schema4.Boolean),
117
- /** Whether the source supports editing (config changes) */
118
- canEdit: Schema4.optional(Schema4.Boolean)
119
- }) {
120
- };
121
- var SourceDetectionResult = class extends Schema4.Class(
122
- "SourceDetectionResult"
123
- )({
124
- /** Plugin kind that detected this source */
125
- kind: Schema4.String,
126
- /** How confident the plugin is that the URL matches */
127
- confidence: Schema4.Literal("high", "medium", "low"),
128
- /** The URL that was probed */
129
- endpoint: Schema4.String,
130
- /** Suggested human-readable name */
131
- name: Schema4.String,
132
- /** Suggested namespace */
133
- namespace: Schema4.String
134
- }) {
135
- };
136
- var SourceRegistry = class extends Context2.Tag("@executor-js/sdk/SourceRegistry")() {
137
- };
138
- var makeInMemorySourceRegistry = () => {
139
- const managers = /* @__PURE__ */ new Map();
140
- const runtimeSources = /* @__PURE__ */ new Map();
141
- return {
142
- addManager: (manager) => Effect2.sync(() => {
143
- managers.set(manager.kind, manager);
144
- }),
145
- registerRuntime: (source) => Effect2.sync(() => {
146
- runtimeSources.set(source.id, source);
147
- }),
148
- unregisterRuntime: (sourceId) => Effect2.sync(() => {
149
- runtimeSources.delete(sourceId);
150
- }),
151
- list: () => Effect2.gen(function* () {
152
- const all = [...runtimeSources.values()];
153
- for (const manager of managers.values()) {
154
- const sources = yield* manager.list();
155
- all.push(...sources);
156
- }
157
- return all;
158
- }),
159
- remove: (sourceId) => Effect2.gen(function* () {
160
- const runtimeSource = runtimeSources.get(sourceId);
161
- if (runtimeSource) {
162
- if (runtimeSource.canRemove) {
163
- runtimeSources.delete(sourceId);
164
- }
165
- return;
166
- }
167
- for (const manager of managers.values()) {
168
- const sources = yield* manager.list();
169
- if (sources.some((s) => s.id === sourceId)) {
170
- yield* manager.remove(sourceId);
171
- return;
172
- }
173
- }
174
- }),
175
- refresh: (sourceId) => Effect2.gen(function* () {
176
- const runtimeSource = runtimeSources.get(sourceId);
177
- if (runtimeSource) {
178
- return;
179
- }
180
- for (const manager of managers.values()) {
181
- const sources = yield* manager.list();
182
- if (sources.some((s) => s.id === sourceId)) {
183
- if (manager.refresh) {
184
- yield* manager.refresh(sourceId);
185
- }
186
- return;
187
- }
188
- }
189
- }),
190
- detect: (url) => Effect2.gen(function* () {
191
- const detectors = [...managers.values()].filter((m) => m.detect).map(
192
- (m) => m.detect(url).pipe(
193
- Effect2.timeout("5 seconds"),
194
- Effect2.catchAll(() => Effect2.succeed(null))
195
- )
196
- );
197
- const results = yield* Effect2.all(detectors, { concurrency: "unbounded" });
198
- return results.filter((r) => r !== null).sort((a, b) => {
199
- const order = { high: 0, medium: 1, low: 2 };
200
- return order[a.confidence] - order[b.confidence];
201
- });
202
- })
203
- };
204
- };
205
-
206
- // src/elicitation.ts
207
- import { Schema as Schema5 } from "effect";
208
- var FormElicitation = class extends Schema5.TaggedClass()("FormElicitation", {
209
- message: Schema5.String,
210
- /** JSON Schema describing the fields to collect */
211
- requestedSchema: Schema5.Record({ key: Schema5.String, value: Schema5.Unknown })
212
- }) {
213
- };
214
- var UrlElicitation = class extends Schema5.TaggedClass()("UrlElicitation", {
215
- message: Schema5.String,
216
- url: Schema5.String,
217
- /** Unique ID so the host can correlate the callback */
218
- elicitationId: Schema5.String
219
- }) {
220
- };
221
- var ElicitationAction = Schema5.Literal("accept", "decline", "cancel");
222
- var ElicitationResponse = class extends Schema5.Class("ElicitationResponse")({
223
- action: ElicitationAction,
224
- /** Present when action is "accept" — the data the user provided */
225
- content: Schema5.optional(Schema5.Record({ key: Schema5.String, value: Schema5.Unknown }))
226
- }) {
227
- };
228
- var ElicitationDeclinedError = class extends Schema5.TaggedError()(
229
- "ElicitationDeclinedError",
230
- {
231
- toolId: ToolId,
232
- action: Schema5.Literal("decline", "cancel")
233
- }
234
- ) {
235
- };
236
-
237
- // src/secrets.ts
238
- import { Context as Context3, Schema as Schema6 } from "effect";
239
- var SecretRef = class extends Schema6.Class("SecretRef")({
240
- id: SecretId,
241
- scopeId: ScopeId,
242
- /** Human-readable label (e.g. "Cloudflare API Token") */
243
- name: Schema6.String,
244
- /** Optional: pin to a specific provider */
245
- provider: Schema6.optionalWith(Schema6.String, { as: "Option" }),
246
- /** What this secret is for */
247
- purpose: Schema6.optional(Schema6.String),
248
- createdAt: Schema6.DateFromNumber
249
- }) {
250
- };
251
- var SetSecretInput = class extends Schema6.Class("SetSecretInput")({
252
- id: SecretId,
253
- scopeId: ScopeId,
254
- name: Schema6.String,
255
- value: Schema6.String,
256
- provider: Schema6.optional(Schema6.String),
257
- purpose: Schema6.optional(Schema6.String)
258
- }) {
259
- };
260
- var SecretStore = class extends Context3.Tag("@executor-js/sdk/SecretStore")() {
261
- };
262
-
263
- // src/policies.ts
264
- import { Context as Context4, Schema as Schema7 } from "effect";
265
- var PolicyAction = Schema7.Literal("allow", "deny", "require_approval");
266
- var Policy = class extends Schema7.Class("Policy")({
267
- id: PolicyId,
268
- scopeId: ScopeId,
269
- name: Schema7.String,
270
- action: PolicyAction,
271
- match: Schema7.Struct({
272
- toolPattern: Schema7.optional(Schema7.String),
273
- sourceId: Schema7.optional(Schema7.String)
274
- }),
275
- priority: Schema7.Number,
276
- createdAt: Schema7.DateFromNumber
277
- }) {
278
- };
279
- var PolicyCheckInput = class extends Schema7.Class("PolicyCheckInput")({
280
- scopeId: ScopeId,
281
- toolId: ToolId
282
- }) {
283
- };
284
- var PolicyEngine = class extends Context4.Tag("@executor-js/sdk/PolicyEngine")() {
285
- };
286
-
287
- // src/scope.ts
288
- import { Schema as Schema8 } from "effect";
289
- var Scope = class extends Schema8.Class("Scope")({
290
- id: ScopeId,
291
- name: Schema8.String,
292
- createdAt: Schema8.DateFromNumber
293
- }) {
294
- };
295
-
296
- // src/plugin.ts
297
- var definePlugin = (plugin) => plugin;
298
-
299
- // src/executor.ts
300
- import { Effect as Effect6 } from "effect";
301
- var resolveElicitationHandler = (options) => options.onElicitation === "accept-all" ? () => Effect6.succeed(new ElicitationResponse({ action: "accept" })) : options.onElicitation;
302
- var createExecutor = (config) => Effect6.gen(function* () {
303
- const { scope, tools, sources, secrets, policies, plugins = [] } = config;
304
- const handles = /* @__PURE__ */ new Map();
305
- const extensions = {};
306
- for (const plugin of plugins) {
307
- const handle = yield* plugin.init({
308
- scope,
309
- tools,
310
- sources,
311
- secrets,
312
- policies
313
- });
314
- handles.set(plugin.key, handle);
315
- extensions[plugin.key] = handle.extension;
316
- }
317
- const base = {
318
- scope,
319
- tools: {
320
- list: (filter) => tools.list(filter),
321
- schema: (toolId) => tools.schema(toolId),
322
- definitions: () => tools.definitions(),
323
- invoke: (toolId, args, options) => {
324
- const tid = toolId;
325
- return Effect6.gen(function* () {
326
- yield* policies.check({ scopeId: scope.id, toolId: tid });
327
- const annotations = yield* tools.resolveAnnotations(tid);
328
- if (annotations?.requiresApproval) {
329
- const handler = resolveElicitationHandler(options);
330
- const response = yield* handler({
331
- toolId: tid,
332
- args,
333
- request: new FormElicitation({
334
- message: annotations.approvalDescription ?? `Approve ${toolId}?`,
335
- requestedSchema: {}
336
- })
337
- });
338
- if (response.action !== "accept") {
339
- return yield* new ElicitationDeclinedError({
340
- toolId: tid,
341
- action: response.action
342
- });
343
- }
344
- }
345
- return yield* tools.invoke(tid, args, options);
346
- });
347
- }
348
- },
349
- sources: {
350
- list: () => sources.list(),
351
- remove: (sourceId) => sources.remove(sourceId),
352
- refresh: (sourceId) => sources.refresh(sourceId),
353
- detect: (url) => sources.detect(url)
354
- },
355
- policies: {
356
- list: () => policies.list(scope.id),
357
- add: (policy) => policies.add({ ...policy, scopeId: scope.id }),
358
- remove: (policyId) => policies.remove(policyId)
359
- },
360
- secrets: {
361
- list: () => secrets.list(scope.id),
362
- resolve: (secretId) => secrets.resolve(secretId, scope.id),
363
- status: (secretId) => secrets.status(secretId, scope.id),
364
- set: (input) => secrets.set({ ...input, scopeId: scope.id }),
365
- remove: (secretId) => secrets.remove(secretId),
366
- addProvider: (provider) => secrets.addProvider(provider),
367
- providers: () => secrets.providers()
368
- },
369
- close: () => Effect6.gen(function* () {
370
- for (const handle of handles.values()) {
371
- if (handle.close) yield* handle.close();
372
- }
373
- })
374
- };
375
- return Object.assign(base, extensions);
376
- });
377
-
378
- // src/plugins/in-memory-tools.ts
379
- import { Effect as Effect7, JSONSchema, Schema as Schema9 } from "effect";
380
-
381
- // src/schema-refs.ts
382
- var REF_PATTERN = /^#\/(?:\$defs|definitions)\/(.+)$/;
383
- var parseRefName = (ref) => ref.match(REF_PATTERN)?.[1];
384
- var normalizeRefs = (node) => {
385
- if (node == null || typeof node !== "object") return node;
386
- if (Array.isArray(node)) {
387
- let changed2 = false;
388
- const out = node.map((item) => {
389
- const n = normalizeRefs(item);
390
- if (n !== item) changed2 = true;
391
- return n;
392
- });
393
- return changed2 ? out : node;
394
- }
395
- const obj = node;
396
- if (typeof obj.$ref === "string") {
397
- const name = parseRefName(obj.$ref);
398
- if (name) {
399
- const canonical = `#/$defs/${name}`;
400
- return canonical !== obj.$ref ? { ...obj, $ref: canonical } : obj;
401
- }
402
- return obj;
403
- }
404
- let changed = false;
405
- const result = {};
406
- for (const [k, v] of Object.entries(obj)) {
407
- const n = normalizeRefs(v);
408
- if (n !== v) changed = true;
409
- result[k] = n;
410
- }
411
- return changed ? result : obj;
412
- };
413
- var hoistDefinitions = (schema) => {
414
- if (schema == null || typeof schema !== "object") {
415
- return { stripped: schema, defs: {} };
416
- }
417
- const obj = schema;
418
- const defs = {};
419
- if (obj.$defs && typeof obj.$defs === "object") {
420
- for (const [k, v] of Object.entries(obj.$defs)) {
421
- defs[k] = v;
422
- }
423
- }
424
- if (obj.definitions && typeof obj.definitions === "object") {
425
- for (const [k, v] of Object.entries(obj.definitions)) {
426
- defs[k] = v;
427
- }
428
- }
429
- const { $defs: _a, definitions: _b, ...rest } = obj;
430
- return { stripped: rest, defs };
431
- };
432
- var collectRefs = (node, defs, found = /* @__PURE__ */ new Set()) => {
433
- if (node == null || typeof node !== "object") return found;
434
- const obj = node;
435
- if (typeof obj.$ref === "string") {
436
- const name = parseRefName(obj.$ref);
437
- if (name && !found.has(name)) {
438
- found.add(name);
439
- const def = defs.get(name);
440
- if (def) collectRefs(def, defs, found);
441
- }
442
- return found;
443
- }
444
- for (const v of Object.values(obj)) {
445
- if (v && typeof v === "object") {
446
- if (Array.isArray(v)) {
447
- for (const item of v) collectRefs(item, defs, found);
448
- } else {
449
- collectRefs(v, defs, found);
450
- }
451
- }
452
- }
453
- return found;
454
- };
455
- var reattachDefs = (schema, defs) => {
456
- if (schema == null || typeof schema !== "object") return schema;
457
- const refs = collectRefs(schema, defs);
458
- if (refs.size === 0) return schema;
459
- const attached = {};
460
- for (const name of refs) {
461
- const def = defs.get(name);
462
- if (def) attached[name] = def;
463
- }
464
- return { ...schema, $defs: attached };
465
- };
466
-
467
- // src/plugins/in-memory-tools.ts
468
- var buildRegistration = (namespace, def) => {
469
- const id = ToolId.make(`${namespace}.${def.name}`);
470
- const decode = Schema9.decodeUnknownSync(def.inputSchema);
471
- const isEffect = def.handler.length >= 2;
472
- const inputJson = JSONSchema.make(def.inputSchema);
473
- const outputJson = def.outputSchema ? JSONSchema.make(def.outputSchema) : void 0;
474
- const inputHoist = hoistDefinitions(inputJson);
475
- const outputHoist = hoistDefinitions(outputJson);
476
- const allDefs = {
477
- ...inputHoist.defs,
478
- ...outputHoist.defs
479
- };
480
- const registration = {
481
- id,
482
- pluginKey: "inMemoryTools",
483
- sourceId: namespace,
484
- name: def.name,
485
- description: def.description,
486
- inputSchema: inputHoist.stripped,
487
- outputSchema: outputHoist.stripped,
488
- mayElicit: isEffect
489
- };
490
- const entry = {
491
- decode,
492
- handler: def.handler,
493
- isEffect
494
- };
495
- return { registration, entry, definitions: allDefs };
496
- };
497
- var makeInvoker = (handlers, pluginCtx) => ({
498
- invoke: (toolId, args, options) => {
499
- const entry = handlers.get(toolId);
500
- if (!entry) {
501
- return Effect7.fail(
502
- new ToolInvocationError({
503
- toolId,
504
- message: `No handler registered for tool "${toolId}"`,
505
- cause: void 0
506
- })
507
- );
508
- }
509
- const parsed = Effect7.try({
510
- try: () => entry.decode(args),
511
- catch: (err) => new ToolInvocationError({
512
- toolId,
513
- message: `Invalid input: ${err instanceof Error ? err.message : String(err)}`,
514
- cause: err
515
- })
516
- });
517
- if (!entry.isEffect) {
518
- return parsed.pipe(
519
- Effect7.flatMap(
520
- (input) => Effect7.try({
521
- try: () => new ToolInvocationResult({
522
- data: entry.handler(input),
523
- error: null
524
- }),
525
- catch: (err) => new ToolInvocationError({
526
- toolId,
527
- message: err instanceof Error ? err.message : String(err),
528
- cause: err
529
- })
530
- })
531
- )
532
- );
533
- }
534
- const ctx = {
535
- sdk: {
536
- secrets: {
537
- list: () => pluginCtx.secrets.list(pluginCtx.scope.id),
538
- resolve: (secretId) => pluginCtx.secrets.resolve(secretId, pluginCtx.scope.id),
539
- status: (secretId) => pluginCtx.secrets.status(secretId, pluginCtx.scope.id),
540
- set: (input) => pluginCtx.secrets.set({
541
- ...input,
542
- scopeId: pluginCtx.scope.id
543
- }),
544
- remove: (secretId) => pluginCtx.secrets.remove(secretId)
545
- }
546
- },
547
- elicit: (request) => Effect7.gen(function* () {
548
- const raw = options?.onElicitation;
549
- if (!raw) {
550
- return yield* new ElicitationDeclinedError({
551
- toolId,
552
- action: "decline"
553
- });
554
- }
555
- const handler = raw === "accept-all" ? () => Effect7.succeed(new ElicitationResponse({ action: "accept" })) : raw;
556
- const response = yield* handler({
557
- toolId,
558
- args,
559
- request
560
- });
561
- if (response.action !== "accept") {
562
- return yield* new ElicitationDeclinedError({
563
- toolId,
564
- action: response.action
565
- });
566
- }
567
- return response.content ?? {};
568
- })
569
- };
570
- const effectHandler = entry.handler;
571
- return parsed.pipe(
572
- Effect7.flatMap((input) => effectHandler(input, ctx)),
573
- Effect7.map((data) => new ToolInvocationResult({ data, error: null })),
574
- Effect7.catchAll(
575
- (err) => {
576
- if (err != null && typeof err === "object" && "_tag" in err && err._tag === "ElicitationDeclinedError") {
577
- return Effect7.fail(err);
578
- }
579
- return Effect7.fail(
580
- new ToolInvocationError({
581
- toolId,
582
- message: err instanceof Error ? err.message : String(err),
583
- cause: err
584
- })
585
- );
586
- }
587
- )
588
- );
589
- }
590
- });
591
- function tool(def) {
592
- return def;
593
- }
594
- var inMemoryToolsPlugin = (config) => {
595
- const ns = config.namespace ?? "memory";
596
- return definePlugin({
597
- key: "inMemoryTools",
598
- init: (ctx) => Effect7.gen(function* () {
599
- const handlers = /* @__PURE__ */ new Map();
600
- const invoker = makeInvoker(handlers, ctx);
601
- yield* ctx.tools.registerInvoker("inMemoryTools", invoker);
602
- const results = config.tools.map((t) => buildRegistration(ns, t));
603
- const allDefs = {};
604
- for (const { definitions } of results) {
605
- Object.assign(allDefs, definitions);
606
- }
607
- yield* ctx.tools.registerDefinitions(allDefs);
608
- for (const { registration, entry } of results) {
609
- handlers.set(registration.id, entry);
610
- }
611
- const registrations = results.map(({ registration }) => registration);
612
- yield* ctx.tools.register(registrations);
613
- return {
614
- extension: {
615
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Schema.Schema is invariant; `any` required to accept arbitrary MemoryToolDefinition types
616
- addTools: (newTools) => Effect7.gen(function* () {
617
- const newResults = newTools.map((t) => buildRegistration(ns, t));
618
- const newDefs = {};
619
- for (const { definitions } of newResults) {
620
- Object.assign(newDefs, definitions);
621
- }
622
- yield* ctx.tools.registerDefinitions(newDefs);
623
- for (const { registration, entry } of newResults) {
624
- handlers.set(registration.id, entry);
625
- }
626
- const newRegistrations = newResults.map(({ registration }) => registration);
627
- yield* ctx.tools.register(newRegistrations);
628
- })
629
- },
630
- close: () => Effect7.gen(function* () {
631
- yield* ctx.tools.unregister(registrations.map((r) => r.id));
632
- for (const { registration } of results) {
633
- handlers.delete(registration.id);
634
- }
635
- })
636
- };
637
- })
638
- });
639
- };
640
-
641
- // src/schema-types.ts
642
- var VALID_IDENTIFIER_PATTERN = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
643
- var REF_PATTERN2 = /^#\/(?:\$defs|definitions)\/(.+)$/;
644
- var asRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
645
- var asStringArray = (value) => Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
646
- var truncate = (value, maxLength) => value.length <= maxLength ? value : `${value.slice(0, Math.max(0, maxLength - 4))} ...`;
647
- var formatPropertyKey = (value) => VALID_IDENTIFIER_PATTERN.test(value) ? value : JSON.stringify(value);
648
- var refNameFromPointer = (ref) => ref.match(REF_PATTERN2)?.[1];
649
- var refFallbackLabel = (ref) => refNameFromPointer(ref) ?? ref.split("/").at(-1) ?? ref;
650
- var summarizeLargeComposite = (schema, maxCompositeMembers) => {
651
- for (const kind of ["oneOf", "anyOf"]) {
652
- const items = schema[kind];
653
- if (Array.isArray(items) && items.length > maxCompositeMembers) {
654
- return { kind, count: items.length };
655
- }
656
- }
657
- return null;
658
- };
659
- var primitiveTypeName = (value) => {
660
- switch (value) {
661
- case "integer":
662
- case "number":
663
- return "number";
664
- case "string":
665
- case "boolean":
666
- case "null":
667
- return value;
668
- case "array":
669
- return "unknown[]";
670
- case "object":
671
- return "Record<string, unknown>";
672
- default:
673
- return "unknown";
674
- }
675
- };
676
- var renderComposite = (input) => {
677
- const rawItems = input.schema[input.key];
678
- const items = Array.isArray(rawItems) ? rawItems.map((item) => asRecord(item)) : [];
679
- if (items.length === 0) {
680
- return null;
681
- }
682
- const labels = items.map((item) => input.render(item, input.depthRemaining - 1)).filter((label) => label.length > 0);
683
- if (labels.length === 0) {
684
- return null;
685
- }
686
- return labels.join(input.key === "allOf" ? " & " : " | ");
687
- };
688
- var localDefinitionsFromSchema = (schema) => {
689
- const root = asRecord(schema);
690
- const defs = /* @__PURE__ */ new Map();
691
- for (const [key, value] of Object.entries(asRecord(root.$defs))) {
692
- defs.set(key, value);
693
- }
694
- for (const [key, value] of Object.entries(asRecord(root.definitions))) {
695
- defs.set(key, value);
696
- }
697
- return defs;
698
- };
699
- var schemaToTypeScriptPreview = (schema, options = {}) => {
700
- const localDefs = localDefinitionsFromSchema(schema);
701
- return schemaToTypeScriptPreviewWithDefs(schema, localDefs, options);
702
- };
703
- var schemaToTypeScriptPreviewWithDefs = (schema, defs, options = {}) => {
704
- const maxLength = options.maxLength ?? 400;
705
- const maxDepth = options.maxDepth ?? 6;
706
- const maxProperties = options.maxProperties ?? 12;
707
- const maxRefDepth = options.maxRefDepth ?? 3;
708
- const maxCompositeMembers = options.maxCompositeMembers ?? 8;
709
- const render = (input) => {
710
- const current = asRecord(input.currentInput);
711
- if (input.depthRemaining <= 0) {
712
- if (typeof current.title === "string" && current.title.length > 0) {
713
- return current.title;
714
- }
715
- if (current.type === "array") {
716
- return "unknown[]";
717
- }
718
- if (current.type === "object" || current.properties) {
719
- return "Record<string, unknown>";
720
- }
721
- return "unknown";
722
- }
723
- if (typeof current.$ref === "string") {
724
- const refLabel = refFallbackLabel(current.$ref);
725
- return input.refDepthRemaining > 0 ? refLabel : `unknown /* ${refLabel} omitted */`;
726
- }
727
- if ("const" in current) {
728
- return JSON.stringify(current.const);
729
- }
730
- const enumValues = Array.isArray(current.enum) ? current.enum : [];
731
- if (enumValues.length > 0) {
732
- return truncate(enumValues.map((value) => JSON.stringify(value)).join(" | "), maxLength);
733
- }
734
- const largeComposite = summarizeLargeComposite(current, maxCompositeMembers);
735
- if (largeComposite) {
736
- return `unknown /* ${largeComposite.count}-way ${largeComposite.kind} omitted */`;
737
- }
738
- const renderNested = (value) => render({
739
- currentInput: value,
740
- depthRemaining: input.depthRemaining - 1,
741
- refDepthRemaining: input.refDepthRemaining
742
- });
743
- const composite = renderComposite({
744
- key: "oneOf",
745
- schema: current,
746
- render: (value) => renderNested(value),
747
- depthRemaining: input.depthRemaining
748
- }) ?? renderComposite({
749
- key: "anyOf",
750
- schema: current,
751
- render: (value) => renderNested(value),
752
- depthRemaining: input.depthRemaining
753
- }) ?? renderComposite({
754
- key: "allOf",
755
- schema: current,
756
- render: (value) => renderNested(value),
757
- depthRemaining: input.depthRemaining
758
- });
759
- if (composite) {
760
- return truncate(composite, maxLength);
761
- }
762
- if (current.nullable === true) {
763
- const { nullable: _nullable, ...rest } = current;
764
- return truncate(
765
- `${render({
766
- currentInput: rest,
767
- depthRemaining: input.depthRemaining,
768
- refDepthRemaining: input.refDepthRemaining
769
- })} | null`,
770
- maxLength
771
- );
772
- }
773
- if (current.type === "array") {
774
- const itemLabel = current.items ? render({
775
- currentInput: current.items,
776
- depthRemaining: input.depthRemaining - 1,
777
- refDepthRemaining: input.refDepthRemaining
778
- }) : "unknown";
779
- return truncate(`${itemLabel}[]`, maxLength);
780
- }
781
- if (current.type === "object" || current.properties) {
782
- const properties = asRecord(current.properties);
783
- const propertyKeys = Object.keys(properties);
784
- const required = new Set(asStringArray(current.required));
785
- const additionalProperties = current.additionalProperties;
786
- const additionalPropertiesLabel = additionalProperties && typeof additionalProperties === "object" ? render({
787
- currentInput: additionalProperties,
788
- depthRemaining: input.depthRemaining - 1,
789
- refDepthRemaining: input.refDepthRemaining
790
- }) : additionalProperties === true ? "unknown" : null;
791
- if (propertyKeys.length === 0) {
792
- if (additionalPropertiesLabel) {
793
- return truncate(`Record<string, ${additionalPropertiesLabel}>`, maxLength);
794
- }
795
- return "Record<string, unknown>";
796
- }
797
- const visibleKeys = propertyKeys.slice(0, maxProperties);
798
- const parts = visibleKeys.map(
799
- (key) => `${formatPropertyKey(key)}${required.has(key) ? "" : "?"}: ${render({
800
- currentInput: properties[key],
801
- depthRemaining: input.depthRemaining - 1,
802
- refDepthRemaining: input.refDepthRemaining
803
- })}`
804
- );
805
- if (visibleKeys.length < propertyKeys.length) {
806
- parts.push("...");
807
- }
808
- if (additionalPropertiesLabel) {
809
- parts.push(`[key: string]: ${additionalPropertiesLabel}`);
810
- }
811
- return truncate(`{ ${parts.join("; ")} }`, maxLength);
812
- }
813
- if (Array.isArray(current.type)) {
814
- return truncate(
815
- current.type.filter((value) => typeof value === "string").map(primitiveTypeName).join(" | "),
816
- maxLength
817
- );
818
- }
819
- if (typeof current.type === "string") {
820
- return primitiveTypeName(current.type);
821
- }
822
- return "unknown";
823
- };
824
- const referencedDepths = /* @__PURE__ */ new Map();
825
- const collectPreviewRefs = (currentInput, refDepth) => {
826
- const current = asRecord(currentInput);
827
- if (summarizeLargeComposite(current, maxCompositeMembers)) {
828
- return;
829
- }
830
- if (typeof current.$ref === "string") {
831
- const name = refNameFromPointer(current.$ref);
832
- if (!name) {
833
- return;
834
- }
835
- const existingDepth = referencedDepths.get(name);
836
- if (existingDepth !== void 0 && existingDepth <= refDepth) {
837
- return;
838
- }
839
- referencedDepths.set(name, refDepth);
840
- if (refDepth >= maxRefDepth) {
841
- return;
842
- }
843
- const target = defs.get(name);
844
- if (target !== void 0) {
845
- collectPreviewRefs(target, refDepth + 1);
846
- }
847
- return;
848
- }
849
- for (const value of Object.values(current)) {
850
- if (value && typeof value === "object") {
851
- if (Array.isArray(value)) {
852
- for (const item of value) {
853
- collectPreviewRefs(item, refDepth);
854
- }
855
- } else {
856
- collectPreviewRefs(value, refDepth);
857
- }
858
- }
859
- }
860
- };
861
- collectPreviewRefs(schema, 1);
862
- const definitions = Object.fromEntries(
863
- [...referencedDepths.entries()].sort(([left], [right]) => left.localeCompare(right)).flatMap(([name, refDepth]) => {
864
- const target = defs.get(name);
865
- if (target === void 0) {
866
- return [];
867
- }
868
- return [
869
- [
870
- name,
871
- render({
872
- currentInput: target,
873
- depthRemaining: maxDepth,
874
- refDepthRemaining: Math.max(0, maxRefDepth - refDepth)
875
- })
876
- ]
877
- ];
878
- })
879
- );
880
- return {
881
- type: render({
882
- currentInput: schema,
883
- depthRemaining: maxDepth,
884
- refDepthRemaining: maxRefDepth
885
- }),
886
- definitions
887
- };
888
- };
889
- var buildToolTypeScriptPreview = (input) => {
890
- const inputPreview = input.inputSchema !== void 0 ? schemaToTypeScriptPreviewWithDefs(input.inputSchema, input.defs, input.options) : null;
891
- const outputPreview = input.outputSchema !== void 0 ? schemaToTypeScriptPreviewWithDefs(input.outputSchema, input.defs, input.options) : null;
892
- const mergedDefinitions = {
893
- ...inputPreview?.definitions,
894
- ...outputPreview?.definitions
895
- };
896
- return {
897
- ...inputPreview ? { inputTypeScript: inputPreview.type } : {},
898
- ...outputPreview ? { outputTypeScript: outputPreview.type } : {},
899
- ...Object.keys(mergedDefinitions).length > 0 ? { typeScriptDefinitions: mergedDefinitions } : {}
900
- };
901
- };
902
-
903
- // src/runtime-tools.ts
904
- import { Effect as Effect8, JSONSchema as JSONSchema2, Schema as Schema10 } from "effect";
905
- var runtimeTool = (def) => def;
906
- var buildRuntimeTool = (pluginKey, sourceId, def) => {
907
- const inputJson = JSONSchema2.make(def.inputSchema);
908
- const outputJson = def.outputSchema ? JSONSchema2.make(def.outputSchema) : void 0;
909
- const inputHoist = hoistDefinitions(inputJson);
910
- const outputHoist = hoistDefinitions(outputJson);
911
- return {
912
- registration: {
913
- id: ToolId.make(def.id),
914
- pluginKey,
915
- sourceId,
916
- name: def.name,
917
- description: def.description,
918
- inputSchema: inputHoist.stripped,
919
- outputSchema: outputHoist.stripped
920
- },
921
- definitions: {
922
- ...inputHoist.defs,
923
- ...outputHoist.defs
924
- },
925
- entry: {
926
- decode: Schema10.decodeUnknownSync(def.inputSchema),
927
- handler: def.handler
928
- }
929
- };
930
- };
931
- var toRuntimeHandler = (toolId, entry) => ({
932
- invoke: (args) => Effect8.try({
933
- try: () => entry.decode(args),
934
- catch: (err) => new ToolInvocationError({
935
- toolId,
936
- message: `Invalid input: ${err instanceof Error ? err.message : String(err)}`,
937
- cause: err
938
- })
939
- }).pipe(
940
- Effect8.flatMap((input) => entry.handler(input)),
941
- Effect8.map((data) => new ToolInvocationResult({ data, error: null })),
942
- Effect8.mapError(
943
- (err) => err instanceof ToolInvocationError ? err : new ToolInvocationError({
944
- toolId,
945
- message: err instanceof Error ? err.message : String(err),
946
- cause: err
947
- })
948
- )
949
- )
950
- });
951
- var registerRuntimeTools = (input) => Effect8.gen(function* () {
952
- const built = yield* Effect8.forEach(
953
- input.tools,
954
- (tool2) => Effect8.sync(() => {
955
- const sourceId = tool2.sourceId ?? input.source?.id;
956
- if (!sourceId) {
957
- throw new Error(
958
- `Runtime tool "${tool2.id}" is missing a sourceId and no shared runtime source was provided`
959
- );
960
- }
961
- return buildRuntimeTool(input.pluginKey, sourceId, tool2);
962
- })
963
- );
964
- if (input.source && input.sources) {
965
- yield* input.sources.registerRuntime(
966
- new Source({
967
- id: input.source.id,
968
- name: input.source.name,
969
- kind: input.source.kind ?? input.pluginKey,
970
- runtime: true,
971
- canRemove: input.source.canRemove ?? false,
972
- canRefresh: input.source.canRefresh ?? false
973
- })
974
- );
975
- }
976
- const defs = {};
977
- for (const tool2 of built) {
978
- Object.assign(defs, tool2.definitions);
979
- yield* input.registry.registerRuntimeHandler(
980
- tool2.registration.id,
981
- toRuntimeHandler(tool2.registration.id, tool2.entry)
982
- );
983
- }
984
- yield* input.registry.registerRuntimeDefinitions(defs);
985
- yield* input.registry.registerRuntime(built.map((tool2) => tool2.registration));
986
- const toolIds = built.map((tool2) => tool2.registration.id);
987
- const defNames = Object.keys(defs);
988
- return {
989
- toolIds,
990
- close: () => Effect8.gen(function* () {
991
- yield* input.registry.unregisterRuntime(toolIds);
992
- yield* input.registry.unregisterRuntimeDefinitions(defNames);
993
- if (input.source && input.sources) {
994
- yield* input.sources.unregisterRuntime(input.source.id);
995
- }
996
- })
997
- };
998
- });
999
-
1000
- // src/in-memory/tool-registry.ts
1001
- import { Effect as Effect9 } from "effect";
1002
- var makeInMemoryToolRegistry = () => {
1003
- const tools = /* @__PURE__ */ new Map();
1004
- const runtimeTools = /* @__PURE__ */ new Map();
1005
- const runtimeHandlers = /* @__PURE__ */ new Map();
1006
- const invokers = /* @__PURE__ */ new Map();
1007
- const sharedDefs = /* @__PURE__ */ new Map();
1008
- const runtimeDefs = /* @__PURE__ */ new Map();
1009
- const getTool = (toolId) => runtimeTools.get(toolId) ?? tools.get(toolId);
1010
- const getDefs = () => {
1011
- const defs = /* @__PURE__ */ new Map();
1012
- for (const [k, v] of sharedDefs) defs.set(k, v);
1013
- for (const [k, v] of runtimeDefs) defs.set(k, v);
1014
- return defs;
1015
- };
1016
- return {
1017
- list: (filter) => Effect9.sync(() => {
1018
- const byId = /* @__PURE__ */ new Map();
1019
- for (const tool2 of tools.values()) byId.set(tool2.id, tool2);
1020
- for (const tool2 of runtimeTools.values()) byId.set(tool2.id, tool2);
1021
- let result = [...byId.values()];
1022
- if (filter?.sourceId) {
1023
- const sid = filter.sourceId;
1024
- result = result.filter((t) => t.sourceId === sid);
1025
- }
1026
- if (filter?.query) {
1027
- const q = filter.query.toLowerCase();
1028
- result = result.filter(
1029
- (t) => t.name.toLowerCase().includes(q) || t.description?.toLowerCase().includes(q)
1030
- );
1031
- }
1032
- return result.map((t) => ({
1033
- id: t.id,
1034
- pluginKey: t.pluginKey,
1035
- sourceId: t.sourceId,
1036
- name: t.name,
1037
- description: t.description
1038
- }));
1039
- }),
1040
- schema: (toolId) => Effect9.fromNullable(getTool(toolId)).pipe(
1041
- Effect9.mapError(() => new ToolNotFoundError({ toolId })),
1042
- Effect9.map((t) => {
1043
- const defs = getDefs();
1044
- const typeScriptPreview = buildToolTypeScriptPreview({
1045
- inputSchema: t.inputSchema,
1046
- outputSchema: t.outputSchema,
1047
- defs,
1048
- options: {
1049
- maxLength: Infinity,
1050
- maxProperties: Infinity,
1051
- maxCompositeMembers: Infinity,
1052
- maxRefDepth: 20
1053
- }
1054
- });
1055
- return {
1056
- id: t.id,
1057
- ...typeScriptPreview,
1058
- inputSchema: t.inputSchema ? reattachDefs(t.inputSchema, defs) : void 0,
1059
- outputSchema: t.outputSchema ? reattachDefs(t.outputSchema, defs) : void 0
1060
- };
1061
- })
1062
- ),
1063
- definitions: () => Effect9.sync(() => {
1064
- const result = {};
1065
- for (const [k, v] of sharedDefs) {
1066
- result[k] = v;
1067
- }
1068
- for (const [k, v] of runtimeDefs) {
1069
- result[k] = v;
1070
- }
1071
- return result;
1072
- }),
1073
- registerDefinitions: (defs) => Effect9.sync(() => {
1074
- for (const [k, v] of Object.entries(defs)) {
1075
- sharedDefs.set(k, normalizeRefs(v));
1076
- }
1077
- }),
1078
- registerRuntimeDefinitions: (defs) => Effect9.sync(() => {
1079
- for (const [k, v] of Object.entries(defs)) {
1080
- runtimeDefs.set(k, normalizeRefs(v));
1081
- }
1082
- }),
1083
- unregisterRuntimeDefinitions: (names) => Effect9.sync(() => {
1084
- for (const name of names) {
1085
- runtimeDefs.delete(name);
1086
- }
1087
- }),
1088
- registerInvoker: (pluginKey, invoker) => Effect9.sync(() => {
1089
- invokers.set(pluginKey, invoker);
1090
- }),
1091
- resolveAnnotations: (toolId) => Effect9.gen(function* () {
1092
- const tool2 = getTool(toolId);
1093
- if (!tool2) return void 0;
1094
- const runtimeHandler = runtimeHandlers.get(toolId);
1095
- if (runtimeHandler?.resolveAnnotations) {
1096
- return yield* runtimeHandler.resolveAnnotations();
1097
- }
1098
- const invoker = invokers.get(tool2.pluginKey);
1099
- if (!invoker?.resolveAnnotations) return void 0;
1100
- return yield* invoker.resolveAnnotations(toolId);
1101
- }),
1102
- invoke: (toolId, args, options) => Effect9.gen(function* () {
1103
- const tool2 = yield* Effect9.fromNullable(getTool(toolId)).pipe(
1104
- Effect9.mapError(() => new ToolNotFoundError({ toolId }))
1105
- );
1106
- const runtimeHandler = runtimeHandlers.get(toolId);
1107
- if (runtimeHandler) {
1108
- return yield* runtimeHandler.invoke(args, options);
1109
- }
1110
- const invoker = invokers.get(tool2.pluginKey);
1111
- if (!invoker) {
1112
- return yield* new ToolInvocationError({
1113
- toolId,
1114
- message: `No invoker registered for plugin "${tool2.pluginKey}"`,
1115
- cause: void 0
1116
- });
1117
- }
1118
- return yield* invoker.invoke(toolId, args, options);
1119
- }),
1120
- register: (newTools) => Effect9.sync(() => {
1121
- for (const t of newTools) {
1122
- tools.set(t.id, {
1123
- ...t,
1124
- inputSchema: normalizeRefs(t.inputSchema),
1125
- outputSchema: normalizeRefs(t.outputSchema)
1126
- });
1127
- }
1128
- }),
1129
- registerRuntime: (newTools) => Effect9.sync(() => {
1130
- for (const t of newTools) {
1131
- runtimeTools.set(t.id, {
1132
- ...t,
1133
- inputSchema: normalizeRefs(t.inputSchema),
1134
- outputSchema: normalizeRefs(t.outputSchema)
1135
- });
1136
- }
1137
- }),
1138
- registerRuntimeHandler: (toolId, handler) => Effect9.sync(() => {
1139
- runtimeHandlers.set(toolId, handler);
1140
- }),
1141
- unregisterRuntime: (toolIds) => Effect9.sync(() => {
1142
- for (const id of toolIds) {
1143
- runtimeTools.delete(id);
1144
- runtimeHandlers.delete(id);
1145
- }
1146
- }),
1147
- unregister: (toolIds) => Effect9.sync(() => {
1148
- for (const id of toolIds) {
1149
- tools.delete(id);
1150
- runtimeTools.delete(id);
1151
- runtimeHandlers.delete(id);
1152
- }
1153
- }),
1154
- unregisterBySource: (sourceId) => Effect9.sync(() => {
1155
- for (const [id, t] of tools) {
1156
- if (t.sourceId === sourceId) {
1157
- tools.delete(id);
1158
- }
1159
- }
1160
- for (const [id, t] of runtimeTools) {
1161
- if (t.sourceId === sourceId) {
1162
- runtimeTools.delete(id);
1163
- runtimeHandlers.delete(id);
1164
- }
1165
- }
1166
- })
1167
- };
1168
- };
1169
-
1170
- // src/in-memory/secret-store.ts
1171
- import { Effect as Effect10, Option } from "effect";
1172
- var makeInMemorySecretProvider = () => {
1173
- const values = /* @__PURE__ */ new Map();
1174
- return {
1175
- key: "memory",
1176
- writable: true,
1177
- get: (key) => Effect10.sync(() => values.get(key) ?? null),
1178
- set: (key, value) => Effect10.sync(() => {
1179
- values.set(key, value);
1180
- }),
1181
- delete: (key) => Effect10.sync(() => values.delete(key)),
1182
- list: () => Effect10.sync(() => [...values.keys()].map((k) => ({ id: k, name: k })))
1183
- };
1184
- };
1185
- var makeInMemorySecretStore = () => {
1186
- const refs = /* @__PURE__ */ new Map();
1187
- const providers = [];
1188
- const defaultProvider = makeInMemorySecretProvider();
1189
- providers.push(defaultProvider);
1190
- const findWritableProvider = (key) => key ? providers.find((p) => p.key === key) : providers.find((p) => p.writable);
1191
- const resolveFromProviders = (secretId, providerKey) => {
1192
- if (providerKey) {
1193
- const provider = providers.find((p) => p.key === providerKey);
1194
- return provider ? provider.get(secretId) : Effect10.succeed(null);
1195
- }
1196
- return Effect10.gen(function* () {
1197
- for (const provider of providers) {
1198
- const value = yield* provider.get(secretId);
1199
- if (value !== null) return value;
1200
- }
1201
- return null;
1202
- });
1203
- };
1204
- return {
1205
- list: (scopeId) => Effect10.sync(() => [...refs.values()].filter((r) => r.scopeId === scopeId)),
1206
- get: (secretId) => Effect10.fromNullable(refs.get(secretId)).pipe(
1207
- Effect10.mapError(() => new SecretNotFoundError({ secretId }))
1208
- ),
1209
- resolve: (secretId, _scopeId) => Effect10.gen(function* () {
1210
- const ref = refs.get(secretId);
1211
- const providerKey = ref ? Option.getOrUndefined(ref.provider) : void 0;
1212
- const value = yield* resolveFromProviders(secretId, providerKey);
1213
- if (value === null) {
1214
- return yield* new SecretResolutionError({
1215
- secretId,
1216
- message: `Secret "${secretId}" not found in any provider`
1217
- });
1218
- }
1219
- return value;
1220
- }),
1221
- status: (secretId, _scopeId) => Effect10.gen(function* () {
1222
- const value = yield* resolveFromProviders(secretId, void 0);
1223
- return value !== null ? "resolved" : "missing";
1224
- }),
1225
- set: (input) => Effect10.gen(function* () {
1226
- const provider = findWritableProvider(input.provider);
1227
- if (!provider?.set) {
1228
- return yield* new SecretResolutionError({
1229
- secretId: input.id,
1230
- message: `No writable provider found${input.provider ? ` (requested: ${input.provider})` : ""}`
1231
- });
1232
- }
1233
- yield* provider.set(input.id, input.value);
1234
- const ref = {
1235
- id: input.id,
1236
- scopeId: input.scopeId,
1237
- name: input.name,
1238
- provider: Option.fromNullable(input.provider),
1239
- purpose: input.purpose,
1240
- createdAt: /* @__PURE__ */ new Date()
1241
- };
1242
- refs.set(input.id, ref);
1243
- return ref;
1244
- }),
1245
- remove: (secretId) => Effect10.gen(function* () {
1246
- const ref = refs.get(secretId);
1247
- if (!ref) return yield* new SecretNotFoundError({ secretId });
1248
- const providerKey = Option.getOrUndefined(ref.provider);
1249
- const provider = findWritableProvider(providerKey);
1250
- if (provider?.delete) {
1251
- yield* provider.delete(secretId);
1252
- }
1253
- refs.delete(secretId);
1254
- return true;
1255
- }),
1256
- addProvider: (provider) => Effect10.sync(() => {
1257
- providers.push(provider);
1258
- }),
1259
- providers: () => Effect10.sync(() => providers.map((p) => p.key))
1260
- };
1261
- };
1262
-
1263
- // src/in-memory/policy-engine.ts
1264
- import { Effect as Effect11 } from "effect";
1265
- var makeInMemoryPolicyEngine = () => {
1266
- const policies = /* @__PURE__ */ new Map();
1267
- let counter = 0;
1268
- return {
1269
- list: (scopeId) => Effect11.succeed([...policies.values()].filter((p) => p.scopeId === scopeId)),
1270
- check: (_input) => Effect11.void,
1271
- add: (policy) => Effect11.sync(() => {
1272
- const id = PolicyId.make(`policy-${++counter}`);
1273
- const full = { ...policy, id, createdAt: /* @__PURE__ */ new Date() };
1274
- policies.set(id, full);
1275
- return full;
1276
- }),
1277
- remove: (policyId) => Effect11.succeed(policies.delete(policyId))
1278
- };
1279
- };
1280
-
1281
- // src/testing.ts
1282
- var makeTestConfig = (options) => {
1283
- const cwd = options?.cwd ?? "/test";
1284
- const scope = {
1285
- id: ScopeId.make("test-scope"),
1286
- name: cwd,
1287
- createdAt: /* @__PURE__ */ new Date()
1288
- };
1289
- return {
1290
- scope,
1291
- tools: makeInMemoryToolRegistry(),
1292
- sources: makeInMemorySourceRegistry(),
1293
- secrets: makeInMemorySecretStore(),
1294
- policies: makeInMemoryPolicyEngine(),
1295
- plugins: options?.plugins
1296
- };
1297
- };
1298
-
1299
- // src/plugin-kv.ts
1300
- import { Effect as Effect12 } from "effect";
1301
- var scopeKv = (kv, namespace) => ({
1302
- get: (key) => kv.get(namespace, key),
1303
- set: (entries) => kv.set(namespace, entries),
1304
- delete: (keys) => kv.delete(namespace, keys),
1305
- list: () => kv.list(namespace),
1306
- deleteAll: () => kv.deleteAll(namespace),
1307
- withTransaction: kv.withTransaction
1308
- });
1309
- var makeInMemoryScopedKv = () => {
1310
- const store = /* @__PURE__ */ new Map();
1311
- return {
1312
- get: (key) => Effect12.succeed(store.get(key) ?? null),
1313
- set: (entries) => Effect12.sync(() => {
1314
- for (const { key, value } of entries) store.set(key, value);
1315
- }),
1316
- delete: (keys) => Effect12.sync(() => {
1317
- let count = 0;
1318
- for (const key of keys) if (store.delete(key)) count++;
1319
- return count;
1320
- }),
1321
- list: () => Effect12.sync(() => [...store.entries()].map(([key, value]) => ({ key, value }))),
1322
- deleteAll: () => Effect12.sync(() => {
1323
- const n = store.size;
1324
- store.clear();
1325
- return n;
1326
- }),
1327
- withTransaction: (effect) => effect
1328
- };
1329
- };
1330
-
1331
- export {
1332
- ScopeId,
1333
- ToolId,
1334
- SecretId,
1335
- PolicyId,
1336
- ToolNotFoundError,
1337
- ToolInvocationError,
1338
- SecretNotFoundError,
1339
- SecretResolutionError,
1340
- PolicyDeniedError,
1341
- ToolAnnotations,
1342
- ToolMetadata,
1343
- ToolSchema,
1344
- ToolInvocationResult,
1345
- ToolListFilter,
1346
- ToolRegistry,
1347
- ToolRegistration,
1348
- Source,
1349
- SourceDetectionResult,
1350
- SourceRegistry,
1351
- makeInMemorySourceRegistry,
1352
- FormElicitation,
1353
- UrlElicitation,
1354
- ElicitationAction,
1355
- ElicitationResponse,
1356
- ElicitationDeclinedError,
1357
- SecretRef,
1358
- SetSecretInput,
1359
- SecretStore,
1360
- PolicyAction,
1361
- Policy,
1362
- PolicyCheckInput,
1363
- PolicyEngine,
1364
- Scope,
1365
- definePlugin,
1366
- createExecutor,
1367
- normalizeRefs,
1368
- hoistDefinitions,
1369
- collectRefs,
1370
- reattachDefs,
1371
- tool,
1372
- inMemoryToolsPlugin,
1373
- schemaToTypeScriptPreview,
1374
- schemaToTypeScriptPreviewWithDefs,
1375
- buildToolTypeScriptPreview,
1376
- runtimeTool,
1377
- registerRuntimeTools,
1378
- makeInMemoryToolRegistry,
1379
- makeInMemorySecretProvider,
1380
- makeInMemorySecretStore,
1381
- makeInMemoryPolicyEngine,
1382
- makeTestConfig,
1383
- scopeKv,
1384
- makeInMemoryScopedKv
1385
- };
1386
- //# sourceMappingURL=chunk-D7CT3UMO.js.map