apps 0.0.1-beta.0 → 0.0.1-beta.1

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 (106) hide show
  1. package/README.md +97 -4
  2. package/framework-reference.json +1 -1
  3. package/js/{chunk-BPEFS4YF.js → chunk-2HHMABB6.js} +70 -14
  4. package/js/{chunk-SBKHUC5L.js → chunk-4LPG6RCH.js} +2 -2
  5. package/js/{chunk-LOKGDT6B.js → chunk-6IIO4NPI.js} +5 -4
  6. package/js/chunk-6YBRWRK3.js +160 -0
  7. package/js/{chunk-7JXHF5IF.js → chunk-BMOIAIVR.js} +1 -1
  8. package/js/chunk-CZ7CSFO4.js +39 -0
  9. package/js/{chunk-YDR4CPJA.js → chunk-EVJUVWN2.js} +8 -8
  10. package/js/{chunk-2OTCEKL2.js → chunk-FW5HBOIK.js} +2352 -1493
  11. package/js/{chunk-EP6AEUZO.js → chunk-FZJOYIZO.js} +1 -1
  12. package/js/{chunk-WIDTG42X.js → chunk-G7IE6BKC.js} +79 -26
  13. package/js/{chunk-VFUZI3NY.js → chunk-HDJH3RPR.js} +4 -4
  14. package/js/{chunk-HP7E42X6.js → chunk-IHQ4ML7K.js} +693 -219
  15. package/js/{chunk-Q2FD5IBM.js → chunk-KOXMLKTM.js} +430 -41
  16. package/js/{chunk-D6BKYP2L.js → chunk-M6ZRRIBI.js} +4 -4
  17. package/js/chunk-NCYXZN2G.js +6274 -0
  18. package/js/{chunk-3ANFZFCV.js → chunk-OHRT55C4.js} +15 -15
  19. package/js/{chunk-R6JMJSVT.js → chunk-PLCMJREA.js} +2 -2
  20. package/js/{chunk-C24KEZXR.js → chunk-PZ36XMXW.js} +36 -2
  21. package/js/{chunk-W7Q5EOTS.js → chunk-QKHR7BMF.js} +32 -32
  22. package/js/{chunk-X3YBZCJW.js → chunk-RBAC33PQ.js} +59 -38
  23. package/js/{chunk-36DNRFZQ.js → chunk-SATWJKN6.js} +1 -1
  24. package/js/chunk-SWPD52J7.js +35 -0
  25. package/js/{chunk-BKVL7XAJ.js → chunk-TE4KO4HI.js} +1 -1
  26. package/js/chunk-W7D7WVSY.js +18 -0
  27. package/js/{chunk-KWTCHVLT.js → chunk-X7SFGU4Q.js} +47 -51
  28. package/js/chunk-YEJOQEII.js +104 -0
  29. package/js/{chunk-OWD2YICM.js → chunk-ZCAMUXSG.js} +116 -87
  30. package/js/chunk-ZJWDMTE3.js +63 -0
  31. package/js/chunk-ZTFQHGEB.js +80 -0
  32. package/js/client.js +11 -11
  33. package/js/contracts.js +81 -25
  34. package/js/effect.js +20 -15
  35. package/js/graphql.js +223 -121
  36. package/js/host.js +75 -19
  37. package/js/index.js +191 -51
  38. package/js/mcp/effect.js +24 -17
  39. package/js/mcp/stdio.js +22 -17
  40. package/js/mcp.js +109 -24
  41. package/js/openapi.js +43897 -143
  42. package/js/operations/approval.js +1 -1
  43. package/js/react.js +4 -4
  44. package/js/skills/effect.js +12 -0
  45. package/js/skills.js +857 -0
  46. package/js/storage/facet.js +7 -7
  47. package/js/ui/auth/contracts.js +6 -6
  48. package/js/ui/auth.js +8 -8
  49. package/js/ui/contracts.js +5 -5
  50. package/js/ui/serving.js +12 -12
  51. package/package.json +9 -1
  52. package/runtime.json +1 -1
  53. package/types/app-cache/src/contracts/cache.d.ts +79 -0
  54. package/types/app-cache/src/index.d.ts +35 -0
  55. package/types/apps/src/contracts/api-response-error.d.ts +43 -0
  56. package/types/apps/src/contracts/app.d.ts +11 -0
  57. package/types/apps/src/contracts/cache.d.ts +41 -0
  58. package/types/apps/src/contracts/dynamic-skills.d.ts +10 -0
  59. package/types/apps/src/contracts/dynamic-tools.d.ts +13 -0
  60. package/types/apps/src/contracts/graphql.d.ts +18 -1
  61. package/types/apps/src/contracts/host.d.ts +200 -7
  62. package/types/apps/src/contracts/mcp.d.ts +3 -1
  63. package/types/apps/src/contracts/openapi-compile.d.ts +11 -0
  64. package/types/apps/src/contracts/openapi-document.d.ts +53 -0
  65. package/types/apps/src/contracts/openapi.d.ts +150 -30
  66. package/types/apps/src/contracts/provider-error.d.ts +15 -0
  67. package/types/apps/src/contracts/provider.d.ts +18 -1
  68. package/types/apps/src/contracts/skills.d.ts +113 -0
  69. package/types/apps/src/contracts/swagger-client.d.ts +29 -0
  70. package/types/apps/src/graphql.d.ts +6 -6
  71. package/types/apps/src/host.d.ts +1 -0
  72. package/types/apps/src/implementation/account-operations.d.ts +122 -3
  73. package/types/apps/src/implementation/app.d.ts +1 -1
  74. package/types/apps/src/implementation/cache-session.d.ts +7 -0
  75. package/types/apps/src/implementation/cache.d.ts +6 -0
  76. package/types/apps/src/implementation/catalog-cache.d.ts +29 -0
  77. package/types/apps/src/implementation/dynamic-skills.d.ts +7 -0
  78. package/types/apps/src/implementation/dynamic-tools.d.ts +8 -0
  79. package/types/apps/src/implementation/elicitation.d.ts +12 -12
  80. package/types/apps/src/implementation/git.d.ts +25 -0
  81. package/types/apps/src/implementation/graphql-catalog.d.ts +10 -0
  82. package/types/apps/src/implementation/graphql.d.ts +81 -3
  83. package/types/apps/src/implementation/inflate.d.ts +16 -0
  84. package/types/apps/src/implementation/input-problems.d.ts +3 -0
  85. package/types/apps/src/implementation/mcp-call.d.ts +3 -2
  86. package/types/apps/src/implementation/mcp-catalog.d.ts +12 -0
  87. package/types/apps/src/implementation/mcp-client.d.ts +9 -8
  88. package/types/apps/src/implementation/mcp-stdio.d.ts +1 -1
  89. package/types/apps/src/implementation/mcp-tools.d.ts +6 -3
  90. package/types/apps/src/implementation/mcp.d.ts +39 -2
  91. package/types/apps/src/implementation/openapi-compile.d.ts +119 -0
  92. package/types/apps/src/implementation/openapi-document.d.ts +53 -0
  93. package/types/apps/src/implementation/openapi-request.d.ts +11 -4
  94. package/types/apps/src/implementation/openapi-source.d.ts +36 -0
  95. package/types/apps/src/implementation/openapi.d.ts +39 -3
  96. package/types/apps/src/implementation/provider-error.d.ts +10 -0
  97. package/types/apps/src/implementation/schema.d.ts +11 -5
  98. package/types/apps/src/implementation/skill-files.d.ts +10 -0
  99. package/types/apps/src/implementation/skills.d.ts +43 -0
  100. package/types/apps/src/index.d.ts +7 -0
  101. package/types/apps/src/mcp.d.ts +5 -5
  102. package/types/apps/src/openapi.d.ts +3 -1
  103. package/types/apps/src/skills.d.ts +72 -0
  104. package/types/telemetry/src/config.d.ts +2 -0
  105. package/js/chunk-22WRQZT7.js +0 -389
  106. package/js/chunk-MLKGABMK.js +0 -9
@@ -1,16 +1,29 @@
1
1
  import {
2
+ folderSkillsEffect
3
+ } from "./chunk-ZTFQHGEB.js";
4
+ import {
5
+ CacheEntry,
6
+ CacheError,
2
7
  authorDatabase,
8
+ cacheLimits,
3
9
  isApp,
4
10
  toEffectApp,
5
- toPromise,
6
11
  unavailableStorage
7
- } from "./chunk-X3YBZCJW.js";
12
+ } from "./chunk-RBAC33PQ.js";
13
+ import {
14
+ fromPromise,
15
+ nativeOperation,
16
+ toPromise
17
+ } from "./chunk-PZ36XMXW.js";
8
18
  import {
9
- nativeOperation
10
- } from "./chunk-C24KEZXR.js";
19
+ parseProviderError
20
+ } from "./chunk-ZJWDMTE3.js";
11
21
  import {
12
22
  DeclaredProvider,
13
23
  DeclaredRequirements,
24
+ ElicitationFailed,
25
+ ElicitationResponse,
26
+ FormElicitation,
14
27
  HostAccountsInvalid,
15
28
  HostDeclarationInvalid,
16
29
  HostError,
@@ -26,22 +39,19 @@ import {
26
39
  HostToolNotFound,
27
40
  HostToolPolicyFailed,
28
41
  HostedTool,
42
+ HostedToolSummary,
29
43
  HostedWebhook,
44
+ HostedWorkflow,
45
+ InvocationDeadline,
30
46
  ManualWebhookSetup,
47
+ ManyAccounts,
48
+ McpError,
49
+ NonRetryableError,
31
50
  OperationToolPrefixes,
32
51
  ResolvedAccounts,
33
52
  ToolResultObservation,
34
53
  TrustedToolApproval,
35
54
  WebhookResponseData,
36
- defaultWebhookTransportLimits
37
- } from "./chunk-22WRQZT7.js";
38
- import {
39
- ElicitationFailed,
40
- ElicitationResponse,
41
- FormElicitation,
42
- HostedWorkflow,
43
- ManyAccounts,
44
- NonRetryableError,
45
55
  WorkflowDuration,
46
56
  WorkflowFailure,
47
57
  WorkflowName,
@@ -49,30 +59,44 @@ import {
49
59
  WorkflowStepOptions,
50
60
  WorkflowValue,
51
61
  approvalElicitation,
62
+ defaultWebhookTransportLimits,
63
+ maxInputProblems,
52
64
  workflowDurationMillis
53
- } from "./chunk-HP7E42X6.js";
65
+ } from "./chunk-IHQ4ML7K.js";
66
+ import {
67
+ AppSkills,
68
+ SkillFile,
69
+ SkillLoadFailed
70
+ } from "./chunk-YEJOQEII.js";
71
+ import {
72
+ OpenapiResponseError
73
+ } from "./chunk-SWPD52J7.js";
54
74
  import {
55
75
  captureTelemetry,
56
76
  invocationFetch
57
- } from "./chunk-OWD2YICM.js";
77
+ } from "./chunk-ZCAMUXSG.js";
58
78
  import {
79
+ decoderOf,
59
80
  importedJsonSchema,
60
81
  jsonSchemaDecoder
61
- } from "./chunk-BPEFS4YF.js";
82
+ } from "./chunk-2HHMABB6.js";
62
83
  import {
63
84
  JsonObject,
64
85
  JsonValue
65
- } from "./chunk-36DNRFZQ.js";
86
+ } from "./chunk-SATWJKN6.js";
66
87
  import {
67
88
  Cause_exports,
89
+ Clock_exports,
90
+ Duration_exports,
68
91
  Effect_exports,
69
92
  Encoding_exports,
70
93
  Match_exports,
71
94
  Option_exports,
72
95
  Redacted_exports,
96
+ SchemaIssue_exports,
73
97
  Schema_exports,
74
98
  Stream_exports
75
- } from "./chunk-2OTCEKL2.js";
99
+ } from "./chunk-FW5HBOIK.js";
76
100
 
77
101
  // src/implementation/elicitation.ts
78
102
  var prepareElicitation = (input) => Effect_exports.gen(function* () {
@@ -156,7 +180,11 @@ var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_expor
156
180
  Effect_exports.timeout(timeout),
157
181
  Effect_exports.catchTag(
158
182
  "TimeoutError",
159
- () => Effect_exports.fail(new WorkflowFailure({ reason: "execution", retryable: true }))
183
+ () => (
184
+ // Both the capability deadline and the native engine deadline describe
185
+ // the same cancellation, regardless of which timer fires first.
186
+ Effect_exports.fail(new WorkflowFailure({ reason: "engine", retryable: true }))
187
+ )
160
188
  )
161
189
  );
162
190
  };
@@ -253,6 +281,23 @@ var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_expor
253
281
  return { runId: execution.runId, step };
254
282
  });
255
283
 
284
+ // src/implementation/input-problems.ts
285
+ var leafHook = (issue) => SchemaIssue_exports.hasInput(issue) ? "Invalid value" : SchemaIssue_exports.defaultLeafHook(issue);
286
+ var checkHook = (issue) => SchemaIssue_exports.hasInput(issue) || SchemaIssue_exports.hasInput(issue.issue) ? SchemaIssue_exports.defaultCheckHook(issue) ?? "Invalid value" : SchemaIssue_exports.defaultCheckHook(issue);
287
+ var format = SchemaIssue_exports.makeFormatterStandardSchemaV1({ leafHook, checkHook });
288
+ var segment = (key) => typeof key === "number" ? `[${key}]` : typeof key === "string" && /^[A-Za-z_$][\w$-]{0,63}$/.test(key) ? `.${key}` : "[key]";
289
+ var inputInvalid = (error) => {
290
+ if (!Schema_exports.isSchemaError(error)) return new HostInputInvalid();
291
+ const problems = format(error.issue).issues.slice(0, maxInputProblems).map(({ path, message }) => {
292
+ const location = (path ?? []).map((key) => segment(typeof key === "object" ? key.key : key));
293
+ return `${location.length === 0 ? "input" : `input${location.join("")}`}: ${message}`.slice(
294
+ 0,
295
+ 512
296
+ );
297
+ });
298
+ return new HostInputInvalid({ problems });
299
+ };
300
+
256
301
  // src/implementation/webhooks.ts
257
302
  var safe = (work, error) => Effect_exports.suspend(work).pipe(
258
303
  Effect_exports.catchCause(
@@ -407,6 +452,204 @@ var dispatchWebhook = (definition, command, context, accounts) => Effect_exports
407
452
  );
408
453
  });
409
454
 
455
+ // ../app-cache/src/index.ts
456
+ var canonical = (value) => {
457
+ if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
458
+ if (value !== null && typeof value === "object")
459
+ return `{${Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, item]) => `${JSON.stringify(key)}:${canonical(item)}`).join(",")}}`;
460
+ return JSON.stringify(value);
461
+ };
462
+ var cacheKey = (key) => Effect_exports.gen(function* () {
463
+ const parsed = yield* Schema_exports.decodeUnknownEffect(Schema_exports.Json)(key).pipe(
464
+ Effect_exports.mapError(() => new CacheError({ reason: "invalid" }))
465
+ );
466
+ const bytes = new TextEncoder().encode(canonical(parsed));
467
+ if (bytes.byteLength > cacheLimits.keyBytes)
468
+ return yield* new CacheError({ reason: "capacity" });
469
+ const hash = yield* Effect_exports.tryPromise({
470
+ try: () => crypto.subtle.digest("SHA-256", bytes),
471
+ catch: () => new CacheError({ reason: "invalid" })
472
+ });
473
+ return [...new Uint8Array(hash)].map((byte) => byte.toString(16).padStart(2, "0")).join("");
474
+ });
475
+ var makeCache = (transport, background, scope = "shared") => {
476
+ const keyOf = (key) => cacheKey([scope, key]);
477
+ const readKeys = (keys) => transport({ operation: "read", keys }).pipe(
478
+ Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(Schema_exports.Array(Schema_exports.NullOr(CacheEntry)))),
479
+ Effect_exports.mapError(() => new CacheError({ reason: "storage" }))
480
+ );
481
+ const durations = (freshFor, staleFor = 0) => Effect_exports.try({
482
+ try: () => {
483
+ const fresh = Duration_exports.toMillis(Duration_exports.fromInputUnsafe(freshFor));
484
+ const stale = Duration_exports.toMillis(Duration_exports.fromInputUnsafe(staleFor));
485
+ if (![fresh, stale].every((value) => Number.isFinite(value) && value >= 0) || fresh + stale > cacheLimits.retentionMs)
486
+ throw new CacheError({ reason: "invalid" });
487
+ return { fresh, stale };
488
+ },
489
+ catch: () => new CacheError({ reason: "invalid" })
490
+ });
491
+ const get = (options, refresh) => Effect_exports.gen(function* () {
492
+ const key = yield* keyOf(options.key);
493
+ const { fresh, stale } = yield* durations(options.freshFor, options.staleFor);
494
+ const decode = (value) => Schema_exports.decodeUnknownEffect(options.schema)(value);
495
+ const load = (lease) => Effect_exports.gen(function* () {
496
+ const value = yield* options.load.pipe(Effect_exports.flatMap(decode));
497
+ const json = yield* Schema_exports.decodeUnknownEffect(Schema_exports.Json)(value).pipe(
498
+ Effect_exports.mapError(() => new CacheError({ reason: "invalid" }))
499
+ );
500
+ const now = yield* Clock_exports.currentTimeMillis;
501
+ const published = yield* transport({
502
+ operation: "publish",
503
+ key,
504
+ lease,
505
+ entry: {
506
+ value: json,
507
+ version: crypto.randomUUID(),
508
+ freshUntil: now + fresh,
509
+ staleUntil: now + fresh + stale
510
+ }
511
+ });
512
+ if (published !== true) return yield* new CacheError({ reason: "unavailable" });
513
+ return value;
514
+ }).pipe(
515
+ Effect_exports.withSpan("app.cache.load"),
516
+ Effect_exports.timeout(cacheLimits.loadTimeoutMs),
517
+ Effect_exports.ensuring(
518
+ transport({ operation: "release", key, lease }).pipe(Effect_exports.catch(() => Effect_exports.void))
519
+ )
520
+ );
521
+ const deadline = (yield* Clock_exports.currentTimeMillis) + cacheLimits.leaseMs;
522
+ let initialVersion;
523
+ while (true) {
524
+ const entry = (yield* readKeys([key]))[0] ?? null;
525
+ const now = yield* Clock_exports.currentTimeMillis;
526
+ if (initialVersion === void 0) initialVersion = entry?.version ?? null;
527
+ const refreshed = refresh && entry !== null && entry.version !== initialVersion;
528
+ if (entry !== null && (refreshed || !refresh && now < entry.freshUntil)) {
529
+ yield* Effect_exports.annotateCurrentSpan("cache.result", "fresh");
530
+ return yield* decode(entry.value);
531
+ }
532
+ const lease = yield* transport({
533
+ operation: "claim",
534
+ key,
535
+ version: entry?.version ?? null
536
+ }).pipe(Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(Schema_exports.NullOr(Schema_exports.String))));
537
+ if (!refresh && entry !== null && now < entry.staleUntil) {
538
+ yield* Effect_exports.annotateCurrentSpan("cache.result", "stale");
539
+ if (lease !== null) yield* background(load(lease).pipe(Effect_exports.asVoid));
540
+ return yield* decode(entry.value);
541
+ }
542
+ if (lease !== null) {
543
+ yield* Effect_exports.annotateCurrentSpan("cache.result", "miss");
544
+ return yield* load(lease);
545
+ }
546
+ if (now >= deadline) return yield* new CacheError({ reason: "timeout" });
547
+ yield* Effect_exports.sleep("100 millis");
548
+ }
549
+ }).pipe(Effect_exports.withSpan("app.cache.get"));
550
+ return {
551
+ /** Read arbitrary retained JSON entries without initiating a refresh. Missing and null are distinct. */
552
+ read: (keys) => Effect_exports.forEach(keys, keyOf).pipe(Effect_exports.flatMap(readKeys)),
553
+ /** Publish bounded immutable parts before publishing the manifest that references them. */
554
+ write: (entries, retention) => Effect_exports.gen(function* () {
555
+ const { fresh } = yield* durations(retention);
556
+ const now = yield* Clock_exports.currentTimeMillis;
557
+ const values = yield* Effect_exports.forEach(
558
+ entries,
559
+ ({ key, value }) => Effect_exports.gen(function* () {
560
+ return {
561
+ key: yield* keyOf(key),
562
+ entry: {
563
+ value,
564
+ version: crypto.randomUUID(),
565
+ freshUntil: now + fresh,
566
+ staleUntil: now + fresh
567
+ }
568
+ };
569
+ })
570
+ );
571
+ yield* transport({ operation: "write", entries: values });
572
+ }),
573
+ /** Revoke retained data and any loader's right to publish its in-flight result. */
574
+ invalidate: (key) => keyOf(key).pipe(
575
+ Effect_exports.flatMap((key2) => transport({ operation: "invalidate", key: key2 })),
576
+ Effect_exports.asVoid
577
+ ),
578
+ /** Read fresh data, refresh stale data in the background, or wait for the lease owner. */
579
+ get: (options) => get(options, false),
580
+ /** Force one awaited refresh without removing the retained value. Concurrent refreshes share a load. */
581
+ revalidate: (options) => get(options, true)
582
+ };
583
+ };
584
+
585
+ // src/implementation/cache.ts
586
+ var unavailableCache = {
587
+ transport: () => Effect_exports.fail(new CacheError({ reason: "unavailable" })),
588
+ background: () => Effect_exports.die(new Error("Cache background runner is unavailable"))
589
+ };
590
+ var authorCache = (host, accounts, signal) => {
591
+ const scoped = (scope, callerSignal = signal) => {
592
+ const cache = makeCache(host.transport, host.background, scope);
593
+ const load = (method, options) => cache[method]({
594
+ key: options.key,
595
+ schema: decoderOf(options.schema),
596
+ freshFor: options.freshFor,
597
+ ...options.staleFor === void 0 ? {} : { staleFor: options.staleFor },
598
+ load: Effect_exports.acquireUseRelease(
599
+ Effect_exports.sync(() => new AbortController()),
600
+ (controller) => invocationFetch(controller.signal).pipe(
601
+ Effect_exports.flatMap(
602
+ (fetch) => fromPromise(options.load)({
603
+ fetch,
604
+ signal: controller.signal,
605
+ cache: scoped(scope, controller.signal)
606
+ })
607
+ )
608
+ ),
609
+ (controller) => Effect_exports.sync(() => controller.abort())
610
+ )
611
+ });
612
+ return {
613
+ get: toPromise((options) => load("get", options), callerSignal),
614
+ revalidate: toPromise(
615
+ (options) => load("revalidate", options),
616
+ callerSignal
617
+ ),
618
+ read: toPromise(
619
+ (key, schema) => cache.read([key]).pipe(
620
+ Effect_exports.flatMap((entries) => {
621
+ const entry = entries[0];
622
+ return entry === void 0 || entry === null ? Effect_exports.succeed(void 0) : Schema_exports.decodeUnknownEffect(decoderOf(schema))(entry.value);
623
+ })
624
+ ),
625
+ callerSignal
626
+ ),
627
+ readMany: toPromise(
628
+ (keys, schema) => cache.read(keys).pipe(
629
+ Effect_exports.flatMap(
630
+ (entries) => Effect_exports.forEach(
631
+ entries,
632
+ (entry) => entry === null ? Effect_exports.succeed(void 0) : Schema_exports.decodeUnknownEffect(decoderOf(schema))(entry.value)
633
+ )
634
+ )
635
+ ),
636
+ callerSignal
637
+ ),
638
+ write: toPromise(cache.write, callerSignal),
639
+ invalidate: toPromise(cache.invalidate, callerSignal),
640
+ forAccount: (account) => {
641
+ const bound = Object.values(accounts).flatMap((value) => Array.isArray(value) ? value : [value]).find((value) => value.id === account.id);
642
+ if (bound === void 0) throw new CacheError({ reason: "invalid" });
643
+ return scoped(
644
+ { account: bound.id, method: bound.method, fields: bound.fields },
645
+ callerSignal
646
+ );
647
+ }
648
+ };
649
+ };
650
+ return scoped("shared");
651
+ };
652
+
410
653
  // src/implementation/host.ts
411
654
  function safe2(work, failure) {
412
655
  return Effect_exports.suspend(work).pipe(
@@ -415,6 +658,18 @@ function safe2(work, failure) {
415
658
  )
416
659
  );
417
660
  }
661
+ var evaluationSafe = (work) => work.pipe(
662
+ Effect_exports.catchCause((cause) => {
663
+ if (Cause_exports.hasInterrupts(cause)) return Effect_exports.interrupt;
664
+ const error = Cause_exports.squash(cause);
665
+ const provider = parseProviderError(error);
666
+ const skills = parseSkillLoadFailed(error);
667
+ const mcp = parseMcpError(error);
668
+ return Effect_exports.fail(
669
+ Option_exports.isSome(provider) ? provider.value : Option_exports.isSome(skills) ? skills.value : Option_exports.isSome(mcp) ? mcp.value : new HostEvaluationFailed()
670
+ );
671
+ })
672
+ );
418
673
  function jsonSchema(decoder) {
419
674
  const imported = importedJsonSchema(decoder);
420
675
  if (imported !== void 0) return Schema_exports.decodeUnknownEffect(JsonObject)(imported);
@@ -468,14 +723,15 @@ function requirements(slots, database) {
468
723
  }
469
724
  return yield* Schema_exports.decodeUnknownEffect(DeclaredRequirements)({
470
725
  accounts: Object.fromEntries(accounts),
726
+ capabilities: { skills: true, toolIndex: true, skillSources: true, scheduledTools: true },
471
727
  ...database === void 0 ? {} : { database }
472
728
  }).pipe(Effect_exports.mapError(() => new HostDeclarationInvalid()));
473
729
  });
474
730
  }
475
- function canonical(value) {
476
- if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
731
+ function canonical2(value) {
732
+ if (Array.isArray(value)) return `[${value.map(canonical2).join(",")}]`;
477
733
  if (value !== null && typeof value === "object") {
478
- return `{${Object.entries(value).sort(([a], [b]) => a.localeCompare(b)).map(([key, item]) => `${JSON.stringify(key)}:${canonical(item)}`).join(",")}}`;
734
+ return `{${Object.entries(value).sort(([a], [b]) => a.localeCompare(b)).map(([key, item]) => `${JSON.stringify(key)}:${canonical2(item)}`).join(",")}}`;
479
735
  }
480
736
  return JSON.stringify(value);
481
737
  }
@@ -504,7 +760,7 @@ function bindAccounts(slots, declarations, context) {
504
760
  for (const account of accounts) {
505
761
  if (ids.has(account.id)) return yield* Effect_exports.fail(new HostAccountsInvalid());
506
762
  ids.add(account.id);
507
- if (canonical(account.provider) !== canonical(requirement.definition) || !Object.hasOwn(provider.auth, account.method))
763
+ if (canonical2(account.provider) !== canonical2(requirement.definition) || !Object.hasOwn(provider.auth, account.method))
508
764
  return yield* Effect_exports.fail(new HostAccountsInvalid());
509
765
  const method = provider.auth[account.method];
510
766
  if (method === void 0) return yield* Effect_exports.fail(new HostAccountsInvalid());
@@ -541,6 +797,26 @@ function dispatch(app, request, context, signal) {
541
797
  (controller) => Effect_exports.sync(() => controller.abort())
542
798
  );
543
799
  const invocationSignal = AbortSignal.any([signal, lifetime.signal]);
800
+ const deadline = context.deadline === void 0 ? void 0 : yield* safe2(
801
+ () => Schema_exports.decodeUnknownEffect(InvocationDeadline)(context.deadline),
802
+ new HostInputInvalid()
803
+ );
804
+ const withinDeadline = (work) => Effect_exports.gen(function* () {
805
+ if (deadline === void 0) return yield* work;
806
+ const remaining = deadline - (yield* Clock_exports.currentTimeMillis);
807
+ if (remaining <= 0)
808
+ return yield* new WorkflowFailure({ reason: "engine", retryable: true });
809
+ const result = yield* work.pipe(
810
+ Effect_exports.timeout(remaining),
811
+ Effect_exports.catchTag(
812
+ "TimeoutError",
813
+ () => Effect_exports.fail(new WorkflowFailure({ reason: "engine", retryable: true }))
814
+ )
815
+ );
816
+ if ((yield* Clock_exports.currentTimeMillis) >= deadline)
817
+ return yield* new WorkflowFailure({ reason: "engine", retryable: true });
818
+ return result;
819
+ });
544
820
  let running;
545
821
  let transactionOpen = false;
546
822
  const delivery = (request2, signal2) => Effect_exports.suspend(
@@ -572,7 +848,16 @@ function dispatch(app, request, context, signal) {
572
848
  get: workflowControls.get,
573
849
  list: workflowControls.list
574
850
  };
851
+ const files = yield* Schema_exports.decodeUnknownEffect(Schema_exports.Array(SkillFile))(
852
+ context.files ?? []
853
+ ).pipe(Effect_exports.mapError(() => new HostDeclarationInvalid()));
575
854
  const bound = {
855
+ cache: authorCache(
856
+ context.cache ?? unavailableCache,
857
+ Redacted_exports.value(context.accounts),
858
+ invocationSignal
859
+ ),
860
+ files,
576
861
  ...yield* bindAccounts(native.accounts, declared, context).pipe(
577
862
  Effect_exports.withSpan("app.accounts.bind")
578
863
  ),
@@ -581,10 +866,22 @@ function dispatch(app, request, context, signal) {
581
866
  fetch: yield* invocationFetch(invocationSignal),
582
867
  elicit: makeElicit(delivery, invocationSignal)
583
868
  };
584
- const definition = yield* safe2(
585
- () => native.evaluate(bound).pipe(Effect_exports.withSpan("app.evaluate")),
586
- new HostEvaluationFailed()
869
+ const definition = yield* evaluationSafe(native.evaluate(bound)).pipe(
870
+ Effect_exports.withSpan("app.evaluate")
587
871
  );
872
+ if (request.operation === "skills") {
873
+ const declared2 = definition.skills ?? (yield* folderSkillsEffect({ files }).pipe(
874
+ Effect_exports.mapError(() => new HostDeclarationInvalid())
875
+ ));
876
+ const source2 = definition.dynamicSkills;
877
+ const dynamic = source2 === void 0 ? [] : yield* evaluationSafe(Effect_exports.suspend(source2.list)).pipe(
878
+ Effect_exports.withSpan("app.skills.load")
879
+ );
880
+ const skills = yield* Schema_exports.decodeUnknownEffect(AppSkills)([...declared2, ...dynamic]).pipe(
881
+ Effect_exports.mapError(() => new HostDeclarationInvalid())
882
+ );
883
+ return request.sources === true ? { skills, dynamic: source2 !== void 0 } : skills;
884
+ }
588
885
  if (request.operation === "workflows") {
589
886
  return yield* Effect_exports.forEach(
590
887
  Object.entries(definition.workflows ?? {}),
@@ -628,6 +925,12 @@ function dispatch(app, request, context, signal) {
628
925
  );
629
926
  return {
630
927
  ...accounts,
928
+ cache: authorCache(
929
+ context.cache ?? unavailableCache,
930
+ Redacted_exports.value(current.accounts),
931
+ signal2
932
+ ),
933
+ files,
631
934
  fetch: yield* invocationFetch(signal2),
632
935
  signal: signal2,
633
936
  runId: execution.runId,
@@ -649,24 +952,34 @@ function dispatch(app, request, context, signal) {
649
952
  );
650
953
  }
651
954
  if (request.operation === "inspect") {
955
+ const summary = request.detail === "summary";
956
+ const wanted = request.tools === void 0 ? void 0 : new Set(request.tools);
652
957
  const metadata = [];
653
958
  for (const [prefix, readOnly, catalog2] of [
654
959
  [OperationToolPrefixes.query, true, definition.queries],
655
960
  [OperationToolPrefixes.mutate, false, definition.mutations]
656
961
  ]) {
657
962
  for (const [name2, operation] of Object.entries(catalog2 ?? {})) {
963
+ if (wanted !== void 0 && !wanted.has(`${prefix}${name2}`)) continue;
964
+ const schedules = Object.entries(definition.schedules ?? {}).filter(([, schedule]) => schedule.tool === `${prefix}${name2}`).map(([name3, { tool: _tool, ...schedule }]) => ({ name: name3, ...schedule }));
965
+ if (request.scheduled === true && schedules.length === 0) continue;
658
966
  metadata.push(
659
967
  yield* safe2(
660
968
  () => Effect_exports.gen(function* () {
661
- return yield* Schema_exports.decodeUnknownEffect(HostedTool)({
969
+ const fields = {
662
970
  name: `${prefix}${name2}`,
663
- schedules: Object.entries(definition.schedules ?? {}).filter(([, schedule]) => schedule.tool === `${prefix}${name2}`).map(([name3, { tool: _tool, ...schedule }]) => ({ name: name3, ...schedule })),
971
+ schedules,
664
972
  description: operation.description ?? `${readOnly ? "Query" : "Mutate"} ${name2}`,
665
973
  ...operation.title === void 0 ? {} : { title: operation.title },
974
+ readOnly,
975
+ annotations: { ...operation.annotations, readOnlyHint: readOnly }
976
+ };
977
+ if (summary)
978
+ return yield* Schema_exports.decodeUnknownEffect(HostedToolSummary)(fields);
979
+ return yield* Schema_exports.decodeUnknownEffect(HostedTool)({
980
+ ...fields,
666
981
  inputSchema: yield* jsonSchema(operation.input),
667
982
  ...operation.output === void 0 ? operation.outputSchema === void 0 ? {} : { outputSchema: operation.outputSchema } : { outputSchema: yield* jsonSchema(operation.output) },
668
- readOnly,
669
- annotations: { ...operation.annotations, readOnlyHint: readOnly },
670
983
  ...operation._meta === void 0 ? {} : { _meta: operation._meta }
671
984
  });
672
985
  }),
@@ -675,6 +988,43 @@ function dispatch(app, request, context, signal) {
675
988
  );
676
989
  }
677
990
  }
991
+ const dynamic = request.scheduled === true ? void 0 : definition.dynamicTools;
992
+ if (dynamic !== void 0 && (wanted === void 0 || metadata.length < wanted.size)) {
993
+ const declared2 = new Set(metadata.map((tool2) => tool2.name));
994
+ const discover = () => {
995
+ if (summary && dynamic.summaries !== void 0) return dynamic.summaries();
996
+ if (wanted !== void 0 && dynamic.describe !== void 0) {
997
+ const describe = dynamic.describe;
998
+ return Effect_exports.forEach(
999
+ [...wanted].filter((name2) => !declared2.has(name2)),
1000
+ (name2) => describe(name2),
1001
+ { concurrency: "unbounded" }
1002
+ ).pipe(Effect_exports.map((tools) => tools.filter((tool2) => tool2 !== void 0)));
1003
+ }
1004
+ return dynamic.list();
1005
+ };
1006
+ const discovered = yield* evaluationSafe(discover()).pipe(
1007
+ Effect_exports.flatMap(
1008
+ (value) => safe2(
1009
+ () => summary ? Schema_exports.decodeUnknownEffect(Schema_exports.Array(HostedToolSummary))(value) : Schema_exports.decodeUnknownEffect(Schema_exports.Array(HostedTool))(value),
1010
+ new HostDeclarationInvalid()
1011
+ )
1012
+ )
1013
+ );
1014
+ const names = new Set(declared2);
1015
+ for (const tool2 of discovered) {
1016
+ const readOnly = tool2.name.startsWith(OperationToolPrefixes.query);
1017
+ if (!readOnly && !tool2.name.startsWith(OperationToolPrefixes.mutate) || tool2.name === OperationToolPrefixes.query || tool2.name === OperationToolPrefixes.mutate || names.has(tool2.name))
1018
+ return yield* new HostDeclarationInvalid();
1019
+ names.add(tool2.name);
1020
+ if (wanted !== void 0 && !wanted.has(tool2.name)) continue;
1021
+ metadata.push({
1022
+ ...tool2,
1023
+ readOnly,
1024
+ annotations: { ...tool2.annotations, readOnlyHint: readOnly }
1025
+ });
1026
+ }
1027
+ }
678
1028
  return metadata;
679
1029
  }
680
1030
  if (request.operation === "webhook-complete" || request.operation === "webhook-validate" || request.operation === "webhooks" || request.operation === "webhook-register" || request.operation === "webhook-handle" || request.operation === "webhook-unregister") {
@@ -682,6 +1032,8 @@ function dispatch(app, request, context, signal) {
682
1032
  definition,
683
1033
  request,
684
1034
  {
1035
+ files,
1036
+ cache: bound.cache,
685
1037
  accounts: bound.accounts,
686
1038
  workflows: workflowControls,
687
1039
  signal: bound.signal,
@@ -708,12 +1060,20 @@ function dispatch(app, request, context, signal) {
708
1060
  const name = request.operation === "call" ? request.tool.slice(OperationToolPrefixes[kind].length) : request.name;
709
1061
  const toolName = `${OperationToolPrefixes[kind]}${name}`;
710
1062
  const catalog = kind === "query" ? definition.queries : definition.mutations;
711
- const tool = catalog !== void 0 && Object.hasOwn(catalog, name) ? catalog[name] : void 0;
1063
+ const declaredTool = catalog !== void 0 && Object.hasOwn(catalog, name) ? catalog[name] : void 0;
1064
+ const source = definition.dynamicTools;
1065
+ const resolvedTool = source === void 0 || declaredTool !== void 0 ? void 0 : yield* evaluationSafe(source.resolve(toolName));
1066
+ const tool = declaredTool ?? resolvedTool;
1067
+ if (tool !== void 0 && tool.kind !== (kind === "query" ? "query" : "mutation"))
1068
+ return yield* new HostDeclarationInvalid();
712
1069
  if (tool === void 0)
713
1070
  return yield* request.operation === "call" ? new HostToolNotFound() : new HostOperationNotFound();
714
- const input = yield* safe2(
715
- () => Schema_exports.decodeUnknownEffect(tool.input)(request.input),
716
- new HostInputInvalid()
1071
+ const input = yield* Effect_exports.suspend(
1072
+ () => Schema_exports.decodeUnknownEffect(tool.input)(request.input)
1073
+ ).pipe(
1074
+ Effect_exports.catchCause(
1075
+ (cause) => Cause_exports.hasInterrupts(cause) ? Effect_exports.interrupt : Effect_exports.fail(inputInvalid(Cause_exports.squash(cause)))
1076
+ )
717
1077
  );
718
1078
  if (context.approval !== void 0) {
719
1079
  const approved = yield* safe2(
@@ -779,9 +1139,6 @@ function dispatch(app, request, context, signal) {
779
1139
  input
780
1140
  );
781
1141
  }).pipe(
782
- Effect_exports.withSpan("app.operation.execute", {
783
- attributes: { "executor.tool.name": toolName, "executor.operation": kind }
784
- }),
785
1142
  Effect_exports.ensuring(
786
1143
  Effect_exports.sync(() => {
787
1144
  running = void 0;
@@ -789,10 +1146,21 @@ function dispatch(app, request, context, signal) {
789
1146
  ),
790
1147
  Effect_exports.catchCause((cause) => {
791
1148
  if (Cause_exports.hasInterrupts(cause)) return Effect_exports.interrupt;
792
- const failure = Schema_exports.decodeUnknownOption(ElicitationFailed)(Cause_exports.squash(cause));
1149
+ const error = Cause_exports.squash(cause);
1150
+ const provider = parseProviderError(error);
1151
+ const response = Schema_exports.decodeUnknownOption(OpenapiResponseError)(error);
1152
+ const failure = Schema_exports.decodeUnknownOption(ElicitationFailed)(error);
793
1153
  return Effect_exports.fail(
794
- Option_exports.isSome(failure) ? failure.value : new HostOperationFailed()
1154
+ Option_exports.isSome(provider) ? provider.value : Option_exports.isSome(response) ? new OpenapiResponseError({
1155
+ code: response.value.code,
1156
+ status: response.value.status,
1157
+ message: response.value.message,
1158
+ ...response.value.recovery === void 0 ? {} : { recovery: response.value.recovery }
1159
+ }) : Option_exports.isSome(failure) ? failure.value : new HostOperationFailed()
795
1160
  );
1161
+ }),
1162
+ Effect_exports.withSpan("app.operation.execute", {
1163
+ attributes: { "executor.tool.name": toolName, "executor.operation": kind }
796
1164
  })
797
1165
  );
798
1166
  const outputSchema = tool.output;
@@ -810,11 +1178,13 @@ function dispatch(app, request, context, signal) {
810
1178
  new HostInputInvalid()
811
1179
  );
812
1180
  if (replay !== void 0 && kind !== "mutate") return yield* new HostInputInvalid();
813
- if (native.database === void 0) return yield* execute();
1181
+ if (native.database === void 0) return yield* withinDeadline(execute());
814
1182
  const storage = context.storage ?? unavailableStorage;
815
1183
  return yield* storage[kind === "query" ? "read" : "mutate"](
816
1184
  native.database.schema,
817
- (db) => replay === void 0 ? execute(db) : db.once(replay.key, replay.fingerprint, () => execute(db))
1185
+ (db) => withinDeadline(
1186
+ replay === void 0 ? execute(db) : db.once(replay.key, replay.fingerprint, () => execute(db))
1187
+ )
818
1188
  ).pipe(
819
1189
  Effect_exports.catchTags({
820
1190
  AppDatabaseError: () => Effect_exports.fail(new HostOperationFailed()),
@@ -825,8 +1195,26 @@ function dispatch(app, request, context, signal) {
825
1195
  })
826
1196
  );
827
1197
  }
1198
+ var parseSkillLoadFailed = (error) => Schema_exports.decodeUnknownOption(SkillLoadFailed)(error).pipe(
1199
+ Option_exports.map(
1200
+ ({ reason, message, status }) => new SkillLoadFailed({
1201
+ reason,
1202
+ ...message ? { message } : {},
1203
+ ...status === void 0 ? {} : { status }
1204
+ })
1205
+ )
1206
+ );
1207
+ var parseMcpError = (error) => Schema_exports.decodeUnknownOption(McpError)(error).pipe(
1208
+ Option_exports.map(
1209
+ ({ phase, reason, status }) => new McpError({ phase, reason, ...status === void 0 ? {} : { status } })
1210
+ )
1211
+ );
828
1212
  var errorStatus = Match_exports.type().pipe(
829
1213
  Match_exports.tagsExhaustive({
1214
+ ProviderError: () => 502,
1215
+ McpError: () => 502,
1216
+ SkillLoadFailed: () => 502,
1217
+ OpenapiResponseError: () => 502,
830
1218
  WorkflowFailure: () => 422,
831
1219
  HostRequestInvalid: () => 400,
832
1220
  HostAccountsInvalid: () => 422,
@@ -895,5 +1283,6 @@ var createAppHandler = (app) => (request, context) => Effect_exports.gen(functio
895
1283
  export {
896
1284
  prepareElicitation,
897
1285
  ApprovalDecision,
1286
+ cacheKey,
898
1287
  createAppHandler
899
1288
  };