@slates/provider-handler 1.0.0-rc.2 → 1.0.0-rc.20

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 (67) hide show
  1. package/dist/index.cjs +1140 -2
  2. package/dist/index.d.cts +8 -0
  3. package/dist/index.d.ts +6 -3
  4. package/dist/index.module.js +1115 -2
  5. package/package.json +11 -11
  6. package/src/index.ts +692 -114
  7. package/src/spec.ts +54 -16
  8. package/src/validation.ts +17 -1
  9. package/src/webhook.test.ts +65 -0
  10. package/src/webhook.ts +69 -0
  11. package/dist/action/action.d.ts +0 -90
  12. package/dist/action/action.d.ts.map +0 -1
  13. package/dist/action/builder.d.ts +0 -27
  14. package/dist/action/builder.d.ts.map +0 -1
  15. package/dist/action/index.d.ts +0 -5
  16. package/dist/action/index.d.ts.map +0 -1
  17. package/dist/action/tool.d.ts +0 -11
  18. package/dist/action/tool.d.ts.map +0 -1
  19. package/dist/action/trigger.d.ts +0 -14
  20. package/dist/action/trigger.d.ts.map +0 -1
  21. package/dist/auth/auth.d.ts +0 -26
  22. package/dist/auth/auth.d.ts.map +0 -1
  23. package/dist/auth/index.d.ts +0 -3
  24. package/dist/auth/index.d.ts.map +0 -1
  25. package/dist/auth/types.d.ts +0 -148
  26. package/dist/auth/types.d.ts.map +0 -1
  27. package/dist/axios/index.d.ts +0 -4
  28. package/dist/axios/index.d.ts.map +0 -1
  29. package/dist/config/config.d.ts +0 -22
  30. package/dist/config/config.d.ts.map +0 -1
  31. package/dist/config/index.d.ts +0 -2
  32. package/dist/config/index.d.ts.map +0 -1
  33. package/dist/context/context.d.ts +0 -20
  34. package/dist/context/context.d.ts.map +0 -1
  35. package/dist/context/hook.d.ts +0 -4
  36. package/dist/context/hook.d.ts.map +0 -1
  37. package/dist/context/index.d.ts +0 -2
  38. package/dist/context/index.d.ts.map +0 -1
  39. package/dist/error/base.d.ts +0 -5
  40. package/dist/error/base.d.ts.map +0 -1
  41. package/dist/error/declaration.d.ts +0 -6
  42. package/dist/error/declaration.d.ts.map +0 -1
  43. package/dist/error/index.d.ts +0 -3
  44. package/dist/error/index.d.ts.map +0 -1
  45. package/dist/index.cjs.map +0 -1
  46. package/dist/index.d.ts.map +0 -1
  47. package/dist/index.modern.js +0 -2
  48. package/dist/index.modern.js.map +0 -1
  49. package/dist/index.module.js.map +0 -1
  50. package/dist/index.umd.js +0 -2
  51. package/dist/index.umd.js.map +0 -1
  52. package/dist/spec.d.ts +0 -14
  53. package/dist/spec.d.ts.map +0 -1
  54. package/dist/specification/index.d.ts +0 -3
  55. package/dist/specification/index.d.ts.map +0 -1
  56. package/dist/specification/slate.d.ts +0 -15
  57. package/dist/specification/slate.d.ts.map +0 -1
  58. package/dist/specification/specification.d.ts +0 -30
  59. package/dist/specification/specification.d.ts.map +0 -1
  60. package/dist/specification/zero.d.ts +0 -13
  61. package/dist/specification/zero.d.ts.map +0 -1
  62. package/dist/state.d.ts +0 -8
  63. package/dist/state.d.ts.map +0 -1
  64. package/dist/tokens.d.ts +0 -34
  65. package/dist/tokens.d.ts.map +0 -1
  66. package/dist/validation.d.ts +0 -4
  67. package/dist/validation.d.ts.map +0 -1
@@ -1,2 +1,1115 @@
1
- import{ServiceError as t,badRequestError as e,notFoundError as n,validationError as r,preconditionFailedError as o}from"@lowerdeck/error";import{createSlatesProviderProtoHandler as i}from"@slates/proto";import{SlateDefaultPollingIntervalSeconds as a,SlateLogger as u,SlateContext as s}from"@slates/provider";import c from"zod";function h(t,e){if(!{}.hasOwnProperty.call(t,e))throw new TypeError("attempted to use private field on non-instance");return t}var l=0;function p(t){return"__private_"+l+++"_"+t}function f(){return f=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var r in n)({}).hasOwnProperty.call(n,r)&&(t[r]=n[r])}return t},f.apply(null,arguments)}function d(t){var e=function(t){if("object"!=typeof t||!t)return t;var e=t[Symbol.toPrimitive];if(void 0!==e){var n=e.call(t,"string");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(t)}(t);return"symbol"==typeof e?e:e+""}var m=function(n,r){var o=n.spec.auth.authStack.find(function(t){return t.key==r});if(!o)throw new t(e({message:"Invalid authentication method ID: "+r}));return o},v=function(t,e){var n;return{id:e.key,name:e.name,type:e.type,scopes:"scopes"in e?e.scopes.map(function(t){return{id:t.scope,title:t.title,description:t.description}}):void 0,inputSchema:(null!=(n=e.inputSchema)?n:c.object({})).toJSONSchema(),outputSchema:t.spec.auth.outputSchema.toJSONSchema(),capabilities:{getDefaultInput:{enabled:!(!("getDefaultInput"in e)||!e.getDefaultInput)},handleTokenRefresh:{enabled:!(!("handleTokenRefresh"in e)||!e.handleTokenRefresh)},handleChangedInput:{enabled:!!e.onInputChanged},getProfile:{enabled:!!e.getProfile}}}},g=function(e,r){var o=e.actions.find(function(t){return t.key==r});if(!o)throw new t(n("action",r));return o},P=function(n,r,o){var i=g(n,o);if(i.type!=r)throw new t(e({message:"Action with ID "+o+" is not of type "+r}));return i},w=function(t,e){var n;return f({},{id:e.key,name:e.name,description:e.description,instructions:e.instructions,constraints:e.constraints,tags:e.tags,metadata:e.metadata,inputSchema:e.inputSchema.toJSONSchema(),outputSchema:e.outputSchema.toJSONSchema()},"tool"==e.type?{type:"action.tool",capabilities:{}}:{type:"action.trigger",capabilities:{},invocation:"polling"==e.source?{type:"polling",intervalSeconds:null!=(n=e.polling.intervalInSeconds)?n:a}:{type:"webhook",autoRegistration:!!e.autoRegisterWebhook,autoUnregistration:!!e.autoUnregisterWebhook}})},y=/*#__PURE__*/p("value"),I=/*#__PURE__*/function(){function t(t){Object.defineProperty(this,y,{writable:!0,value:void 0}),h(this,y)[y]=t}var e,n,r=t.prototype;return r.get=function(){return h(this,y)[y]},r.set=function(t){h(this,y)[y]=t},e=t,(n=[{key:"value",get:function(){return h(this,y)[y]}}])&&function(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,d(r.key),r)}}(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),e}(),b=function(e,n,o,i){var a=e.safeParse(n);if(!a.success)throw new t(function(t,e,n){return r({message:e,entity:t,errors:n.issues.map(function(t){return f({},t,{path:t.path.map(function(t){return String(t)})})})})}(o,i,a.error));return a.data},S=function(n,r){return i(function(i){try{var a=new I(null),c=new I(null),h=new I(null),l=new I(null),p=new I(null),d=new u(r),y=function(){var e=a.get(),n=c.get();if(!e||!n)throw new t(o({message:"Connection context has not been initialized"}));return{protocol:e,participants:n}},S=function(){var e=y(),r=l.get(),i=p.get(),a=h.get();if(!r||!i||!a&&n.spec.auth.authStack.length>0)throw new t(o({message:"Session context has not been initialized"}));return f({},e,{config:r.value,session:i,auth:a})};return i.onNotification("slates/hello",function(t){var e=t.params;try{return a.set(e.protocol),Promise.resolve()}catch(t){return Promise.reject(t)}}),i.onNotification("slates/participant.set",function(e){var n=e.params;try{if(!a.get())throw new t(o({message:"Connection protocol has not been initialized"}));return c.set(n.participants),Promise.resolve()}catch(t){return Promise.reject(t)}}),i.onNotification("slates/auth.set",function(t){var e=t.params;try{y(),m(n,e.authenticationMethodId);var r=b(n.spec.authSchema,e.output,"auth","Invalid authentication output for method ID: "+e.authenticationMethodId);return h.set({authenticationMethodId:e.authenticationMethodId,output:r}),Promise.resolve()}catch(t){return Promise.reject(t)}}),i.onNotification("slates/config.set",function(t){var e=t.params;try{y();var r=b(n.spec.configSchema,e.config,"config","Invalid configuration");return l.set({value:r}),Promise.resolve()}catch(t){return Promise.reject(t)}}),i.onNotification("slates/session.start",function(t){var e=t.params;try{return y(),p.set({id:e.sessionId,state:e.state}),Promise.resolve()}catch(t){return Promise.reject(t)}}),i.onRequest("slates/config.changed",function(t){var e=t.params;try{y();var r=b(n.spec.config.configSchema,e.newConfig,"config","Invalid configuration"),o=n.spec.config.handlers.configChanged;return o?Promise.resolve(o({previousConfig:e.previousConfig,newConfig:r})).then(function(t){var e;return{success:!0,config:null!=(e=null==t?void 0:t.config)?e:r}}):Promise.resolve({success:!0,config:r})}catch(t){return Promise.reject(t)}}),i.onRequest("slates/config.get_default",function(t){try{y();var e=n.spec.config.handlers.getDefaultConfig;return e?Promise.resolve(e()).then(function(t){return{config:t}}):Promise.resolve({config:null})}catch(t){return Promise.reject(t)}}),i.onRequest("slates/config.schema.get",function(t){try{return y(),Promise.resolve({schema:n.spec.configSchema.toJSONSchema()})}catch(t){return Promise.reject(t)}}),i.onRequest("slates/provider.identify",function(t){try{return y(),Promise.resolve({protocol:"slates@2026-01-01",provider:{type:"provider",id:n.spec.key,name:n.spec.name,description:n.spec.description,metadata:n.spec.parameters.metadata}})}catch(t){return Promise.reject(t)}}),i.onRequest("slates/auth.methods.list",function(t){try{return y(),Promise.resolve({authenticationMethods:n.spec.auth.authStack.map(function(t){return v(n,t)})})}catch(t){return Promise.reject(t)}}),i.onRequest("slates/auth.method.get",function(t){var e=t.params;try{y();var r=m(n,e.authenticationMethodId);return Promise.resolve({authenticationMethod:v(n,r)})}catch(t){return Promise.reject(t)}}),i.onRequest("slates/auth.input.get_default",function(t){var e=t.params;try{y();var r=m(n,e.authenticationMethodId);return r.getDefaultInput?Promise.resolve(r.getDefaultInput()).then(function(t){return{input:t}}):Promise.resolve({input:null})}catch(t){return Promise.reject(t)}}),i.onRequest("slates/auth.input.changed",function(t){var e=t.params;try{y();var r=m(n,e.authenticationMethodId);return r.onInputChanged?Promise.resolve(r.onInputChanged({previousInput:e.previousInput,newInput:e.newInput})).then(function(t){var n;return{success:!0,input:null!=(n=null==t?void 0:t.input)?n:e.newInput}}):Promise.resolve({success:!0,input:e.newInput})}catch(t){return Promise.reject(t)}}),i.onRequest("slates/auth.output.get",function(t){var e=t.params;try{var r,o=function(t){return r?t:{output:a}};y();var i=m(n,e.authenticationMethodId),a=e.input;i.inputSchema&&(a=b(i.inputSchema,a,"auth","Invalid authentication input for method ID: "+e.authenticationMethodId));var u=function(){if("getOutput"in i)return Promise.resolve(i.getOutput({input:a})).then(function(t){return r=1,{output:t.output}})}();return Promise.resolve(u&&u.then?u.then(o):o(u))}catch(t){return Promise.reject(t)}}),i.onRequest("slates/auth.authorization_callback.handle",function(e){var r=e.params;try{var i,a=function(e){if(i)return e;throw new t(o({message:"Authentication method does not support authorization callback handling: "+r.authenticationMethodId}))};y();var u=m(n,r.authenticationMethodId),s=function(){if("handleCallback"in u)return Promise.resolve(u.handleCallback({code:r.code,state:r.state,redirectUri:r.redirectUri,input:r.input,clientId:r.clientId,clientSecret:r.clientSecret,scopes:r.scopes})).then(function(t){return i=1,{output:t.output,input:t.input}})}();return Promise.resolve(s&&s.then?s.then(a):a(s))}catch(t){return Promise.reject(t)}}),i.onRequest("slates/auth.authorization_url.get",function(e){var r=e.params;try{var i,a=function(e){if(i)return e;throw new t(o({message:"Authentication method does not support authorization URL retrieval: "+r.authenticationMethodId}))};y();var u=m(n,r.authenticationMethodId),s=function(){if("getAuthorizationUrl"in u)return Promise.resolve(u.getAuthorizationUrl({redirectUri:r.redirectUri,state:r.state,input:r.input,clientId:r.clientId,clientSecret:r.clientSecret,scopes:r.scopes})).then(function(t){return i=1,{authorizationUrl:t.url,input:t.input}})}();return Promise.resolve(s&&s.then?s.then(a):a(s))}catch(t){return Promise.reject(t)}}),i.onRequest("slates/auth.profile.get",function(e){var r=e.params;try{var i,a=function(e){if(i)return e;throw new t(o({message:"Authentication method does not support profile retrieval: "+r.authenticationMethodId}))};y();var u=m(n,r.authenticationMethodId),s=function(){if(u.getProfile)return Promise.resolve(u.getProfile({output:r.output,input:r.input,scopes:r.scopes})).then(function(t){return i=1,{profile:t.profile}})}();return Promise.resolve(s&&s.then?s.then(a):a(s))}catch(t){return Promise.reject(t)}}),i.onRequest("slates/auth.token_refresh.handle",function(e){var r=e.params;try{var i,a=function(e){if(i)return e;throw new t(o({message:"Authentication method does not support token refresh handling: "+r.authenticationMethodId}))};y();var u=m(n,r.authenticationMethodId),s=function(){if("handleTokenRefresh"in u&&u.handleTokenRefresh)return Promise.resolve(u.handleTokenRefresh({output:r.output,input:r.input,clientId:r.clientId,clientSecret:r.clientSecret,scopes:r.scopes})).then(function(t){return i=1,{output:t.output,input:t.input}})}();return Promise.resolve(s&&s.then?s.then(a):a(s))}catch(t){return Promise.reject(t)}}),i.onRequest("slates/actions.list",function(t){try{return y(),Promise.resolve({actions:n.actions.map(function(t){return w(0,t)})})}catch(t){return Promise.reject(t)}}),i.onRequest("slates/action.get",function(t){var e=t.params;try{y();var r=g(n,e.actionId);return Promise.resolve({action:w(0,r)})}catch(t){return Promise.reject(t)}}),i.onRequest("slates/action.tool.invoke",function(t){var e=t.params;try{var r,o=S(),i=P(n,"tool",e.actionId),a=b(i.inputSchema,e.input,"input","Invalid input for tool ID: "+e.actionId);return Promise.resolve(i.handleInvocation(new s(o.config,a,null==(r=o.auth)?void 0:r.output,n.spec,d))).then(function(t){return{output:t.output,message:t.message}})}catch(t){return Promise.reject(t)}}),i.onRequest("slates/action.trigger.map_event",function(t){var e=t.params;try{var r,o=S(),i=P(n,"trigger",e.actionId),a=b(i.inputSchema,e.input,"input","Invalid event for trigger ID: "+e.actionId);return Promise.resolve(i.handleEvent(new s(o.config,a,null==(r=o.auth)?void 0:r.output,n.spec,d))).then(function(t){return{id:t.id,type:t.type,output:t.output}})}catch(t){return Promise.reject(t)}}),i.onRequest("slates/action.trigger.poll_events",function(r){var o=r.params;try{var i,a=S(),u=P(n,"trigger",o.actionId);if(!u.pollEvents)throw new t(e({message:"Trigger action does not support polling: "+o.actionId}));return Promise.resolve(u.pollEvents(new s(a.config,{state:o.state},null==(i=a.auth)?void 0:i.output,n.spec,d))).then(function(t){return{inputs:t.inputs,updatedState:t.updatedState}})}catch(t){return Promise.reject(t)}}),i.onRequest("slates/action.trigger.webhook_handle",function(r){var o=r.params;try{var i,a=S(),u=P(n,"trigger",o.actionId);if(!u.handleRequest)throw new t(e({message:"Trigger action does not support webhook requests: "+o.actionId}));var c=new Request(o.url,{method:o.method,headers:o.headers,body:o.body?Uint8Array.from(atob(o.body.content),function(t){return t.charCodeAt(0)}):null});return Promise.resolve(u.handleRequest(new s(a.config,{request:c,state:o.state},null==(i=a.auth)?void 0:i.output,n.spec,d))).then(function(t){return{inputs:t.inputs,updatedState:t.updatedState}})}catch(t){return Promise.reject(t)}}),i.onRequest("slates/action.trigger.webhook_register",function(r){var o=r.params;try{var i,a=S(),u=P(n,"trigger",o.actionId);if(!u.autoRegisterWebhook)throw new t(e({message:"Trigger action does not support webhook auto-registration: "+o.actionId}));return Promise.resolve(u.autoRegisterWebhook(new s(a.config,{webhookBaseUrl:o.webhookBaseUrl},null==(i=a.auth)?void 0:i.output,n.spec,d))).then(function(t){return{registrationDetails:t.registrationDetails,state:t.state}})}catch(t){return Promise.reject(t)}}),i.onRequest("slates/action.trigger.webhook_unregister",function(r){var o=r.params;try{var i,a=S(),u=P(n,"trigger",o.actionId);if(!u.autoUnregisterWebhook)throw new t(e({message:"Trigger action does not support webhook auto-unregistration: "+o.actionId}));return Promise.resolve(u.autoUnregisterWebhook(new s(a.config,{webhookBaseUrl:o.webhookBaseUrl,registrationDetails:o.registrationDetails,state:o.state},null==(i=a.auth)?void 0:i.output,n.spec,d))).then(function(){return{}})}catch(t){return Promise.reject(t)}}),Promise.resolve()}catch(t){return Promise.reject(t)}})};export{S as createProviderHandler};
2
- //# sourceMappingURL=index.module.js.map
1
+ // src/index.ts
2
+ import { badRequestError as badRequestError3, preconditionFailedError, ServiceError as ServiceError4 } from "@lowerdeck/error";
3
+ import {
4
+ createSlatesProviderProtoHandler,
5
+ SLATES_PROTOCOL_VERSION
6
+ } from "@slates/proto";
7
+ import {
8
+ runWithContext,
9
+ SlateContext,
10
+ SlateLogger,
11
+ SlatePublicContext
12
+ } from "@slates/provider";
13
+
14
+ // src/spec.ts
15
+ import { badRequestError, notFoundError, ServiceError as ServiceError2 } from "@lowerdeck/error";
16
+ import {
17
+ SlateDefaultPollingIntervalSeconds
18
+ } from "@slates/provider";
19
+ import z from "zod";
20
+
21
+ // src/validation.ts
22
+ import { ServiceError, validationError } from "@lowerdeck/error";
23
+ var zodToValidationError = (entity, message, e) => {
24
+ return validationError({
25
+ message,
26
+ entity,
27
+ errors: e.issues.map((i) => ({
28
+ ...i,
29
+ path: i.path.map((p) => String(p))
30
+ }))
31
+ });
32
+ };
33
+ var validate = (schema, data, entity, message) => {
34
+ let result = schema.safeParse(data);
35
+ if (!result.success) {
36
+ throw new ServiceError(zodToValidationError(entity, message, result.error));
37
+ }
38
+ return result.data;
39
+ };
40
+ var toJsonSchema = (schema) => schema.toJSONSchema({
41
+ unrepresentable: "any",
42
+ override: (ctx) => {
43
+ let def = ctx.zodSchema._zod.def;
44
+ if (def.type === "date") {
45
+ ctx.jsonSchema.type = "string";
46
+ ctx.jsonSchema.format = "date-time";
47
+ }
48
+ if (def.type === "bigint") {
49
+ ctx.jsonSchema.type = "number";
50
+ }
51
+ }
52
+ });
53
+
54
+ // src/spec.ts
55
+ var getAuthMethod = (slate, authenticationMethodId) => {
56
+ let authMethod = slate.spec.auth.authStack.find((m) => m.key === authenticationMethodId);
57
+ if (!authMethod) {
58
+ throw new ServiceError2(
59
+ badRequestError({
60
+ message: `Invalid authentication method ID: ${authenticationMethodId}`
61
+ })
62
+ );
63
+ }
64
+ return authMethod;
65
+ };
66
+ var mapAuthMethod = (slate, m) => ({
67
+ id: m.key,
68
+ name: m.name,
69
+ type: m.type,
70
+ scopes: "scopes" in m ? m.scopes.map((s) => ({
71
+ id: s.scope,
72
+ title: s.title,
73
+ description: s.description,
74
+ defaultChecked: s.defaultChecked
75
+ })) : void 0,
76
+ inputSchema: toJsonSchema(m.inputSchema ?? z.object({})),
77
+ outputSchema: toJsonSchema(slate.spec.auth.outputSchema),
78
+ capabilities: {
79
+ getDefaultInput: { enabled: !!("getDefaultInput" in m && m.getDefaultInput) },
80
+ handleTokenRefresh: {
81
+ enabled: !!("handleTokenRefresh" in m && m.handleTokenRefresh)
82
+ },
83
+ handleChangedInput: {
84
+ enabled: !!m.onInputChanged
85
+ },
86
+ getProfile: { enabled: !!m.getProfile }
87
+ },
88
+ docs: m.docs ?? []
89
+ });
90
+ var getAction = (slate, actionId) => {
91
+ let action = slate.actions.find((m) => m.key === actionId);
92
+ if (!action) {
93
+ throw new ServiceError2(notFoundError(`action`, actionId));
94
+ }
95
+ return action;
96
+ };
97
+ var getAdapter = (slate, adapterId) => {
98
+ let adapter = slate.adapters.find((m) => m.id === adapterId);
99
+ if (!adapter) {
100
+ throw new ServiceError2(notFoundError(`adapter`, adapterId));
101
+ }
102
+ return adapter;
103
+ };
104
+ var mapAdapter = (adapter) => ({
105
+ id: adapter.id,
106
+ name: adapter.name,
107
+ capabilities: adapter.capabilities
108
+ });
109
+ var getActionWithType = (slate, type, actionId) => {
110
+ let action = getAction(slate, actionId);
111
+ if (action.type !== type) {
112
+ throw new ServiceError2(
113
+ badRequestError({
114
+ message: `Action with ID ${actionId} is not of type ${type}`
115
+ })
116
+ );
117
+ }
118
+ return action;
119
+ };
120
+ var mapAction = (_slate, a) => {
121
+ let base = {
122
+ id: a.key,
123
+ name: a.name,
124
+ description: a.description,
125
+ instructions: a.instructions,
126
+ constraints: a.constraints,
127
+ tags: a.tags,
128
+ metadata: a.metadata,
129
+ scopes: a.scopes,
130
+ authMethods: a.authMethods,
131
+ docs: a.docs ?? [],
132
+ ...a.adapter ? { adapter: a.adapter } : {},
133
+ inputSchema: toJsonSchema(a.inputSchema),
134
+ outputSchema: toJsonSchema(a.outputSchema)
135
+ };
136
+ if (a.type === "tool") {
137
+ return {
138
+ ...base,
139
+ type: "action.tool",
140
+ capabilities: {},
141
+ isPublic: a.isPublic
142
+ };
143
+ }
144
+ return {
145
+ ...base,
146
+ type: "action.trigger",
147
+ capabilities: {},
148
+ invocation: a.source === "polling" ? {
149
+ type: "polling",
150
+ intervalSeconds: a.polling.intervalInSeconds ?? SlateDefaultPollingIntervalSeconds
151
+ } : {
152
+ type: "webhook",
153
+ autoRegistration: !!a.autoRegisterWebhook,
154
+ autoUnregistration: !!a.autoUnregisterWebhook,
155
+ http: a.http
156
+ }
157
+ };
158
+ };
159
+
160
+ // src/state.ts
161
+ var State = class {
162
+ #value;
163
+ get value() {
164
+ return this.#value;
165
+ }
166
+ get() {
167
+ return this.#value;
168
+ }
169
+ set(value) {
170
+ this.#value = value;
171
+ }
172
+ constructor(initialValue) {
173
+ this.#value = initialValue;
174
+ }
175
+ };
176
+
177
+ // src/webhook.ts
178
+ import { badRequestError as badRequestError2, ServiceError as ServiceError3 } from "@lowerdeck/error";
179
+ var SLATE_WEBHOOK_RESPONSE_MAX_BODY_BYTES = 1024 * 1024;
180
+ var serializeBody = (body) => {
181
+ if (body === null) return null;
182
+ if (body.byteLength > SLATE_WEBHOOK_RESPONSE_MAX_BODY_BYTES) {
183
+ throw new ServiceError3(
184
+ badRequestError2({
185
+ message: `Webhook response body exceeds the ${SLATE_WEBHOOK_RESPONSE_MAX_BODY_BYTES}-byte limit`
186
+ })
187
+ );
188
+ }
189
+ return {
190
+ encoding: "base64",
191
+ content: Buffer.from(body).toString("base64")
192
+ };
193
+ };
194
+ var headersToObject = (headers) => {
195
+ let result = {};
196
+ headers.forEach((value, key) => {
197
+ result[key] = value;
198
+ });
199
+ return result;
200
+ };
201
+ var validateStatus = (status) => {
202
+ if (!Number.isInteger(status) || status < 100 || status > 599) {
203
+ throw new ServiceError3(
204
+ badRequestError2({
205
+ message: "Webhook response status must be an integer between 100 and 599"
206
+ })
207
+ );
208
+ }
209
+ };
210
+ var serializeWebhookHttpResponse = async (response) => {
211
+ if (response instanceof Response) {
212
+ validateStatus(response.status);
213
+ return {
214
+ status: response.status,
215
+ headers: headersToObject(response.headers),
216
+ body: serializeBody(
217
+ response.body === null ? null : new Uint8Array(await response.arrayBuffer())
218
+ )
219
+ };
220
+ }
221
+ let status = response.status ?? 200;
222
+ validateStatus(status);
223
+ let body = typeof response.body === "string" ? new TextEncoder().encode(response.body) : response.body ?? null;
224
+ return {
225
+ status,
226
+ headers: response.headers ?? {},
227
+ body: serializeBody(body)
228
+ };
229
+ };
230
+
231
+ // src/index.ts
232
+ var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
233
+ var getObjectKeyCount = (value) => isRecord(value) ? Object.keys(value).length : void 0;
234
+ var DOWNLOAD_ATTACHMENT_URL_KEYS = /* @__PURE__ */ new Set([
235
+ "downloadUrl",
236
+ "fileUrl",
237
+ "temporaryDownloadUrl",
238
+ "webContentLink"
239
+ ]);
240
+ var isAttachmentUrl = (value) => /^[a-z][a-z0-9+.-]*:\/\//i.test(value);
241
+ var collectOutputUrlAttachments = (value, seen = /* @__PURE__ */ new Set()) => {
242
+ if (Array.isArray(value)) {
243
+ return value.flatMap((item) => collectOutputUrlAttachments(item, seen));
244
+ }
245
+ if (!isRecord(value)) {
246
+ return [];
247
+ }
248
+ let attachments = [];
249
+ for (let [key, nestedValue] of Object.entries(value)) {
250
+ if (DOWNLOAD_ATTACHMENT_URL_KEYS.has(key) && typeof nestedValue === "string" && nestedValue.length > 0 && isAttachmentUrl(nestedValue) && !seen.has(nestedValue)) {
251
+ seen.add(nestedValue);
252
+ attachments.push({
253
+ content: {
254
+ type: "url",
255
+ url: nestedValue
256
+ }
257
+ });
258
+ continue;
259
+ }
260
+ attachments.push(...collectOutputUrlAttachments(nestedValue, seen));
261
+ }
262
+ return attachments;
263
+ };
264
+ var mergeAttachments = (explicitAttachments, output) => {
265
+ let attachments = [...explicitAttachments ?? []];
266
+ let seen = new Set(attachments.map((attachment) => JSON.stringify(attachment)));
267
+ for (let attachment of collectOutputUrlAttachments(output)) {
268
+ let key = JSON.stringify(attachment);
269
+ if (seen.has(key)) continue;
270
+ seen.add(key);
271
+ attachments.push(attachment);
272
+ }
273
+ return attachments.length > 0 ? attachments : void 0;
274
+ };
275
+ var toErrorMetadata = (error) => {
276
+ if (error instanceof Error) {
277
+ return {
278
+ errorName: error.name,
279
+ errorMessage: error.message,
280
+ errorStack: error.stack
281
+ };
282
+ }
283
+ return {
284
+ errorValue: String(error)
285
+ };
286
+ };
287
+ var formatEntityLabel = (name, key) => `"${name}" (${key})`;
288
+ var resolveTraceMessage = (message, result) => typeof message === "function" ? message(result) : message;
289
+ var createProviderHandler = (slate, listeners) => createSlatesProviderProtoHandler(async (manager) => {
290
+ let protocol = new State(null);
291
+ let participants = new State(null);
292
+ let auth = new State(null);
293
+ let config = new State(null);
294
+ let session = new State(null);
295
+ let logger = new SlateLogger(listeners);
296
+ let providerTrace = {
297
+ providerId: slate.spec.key,
298
+ providerName: slate.spec.name
299
+ };
300
+ let traceProviderCall = async (trace, handler) => {
301
+ let startedAt = Date.now();
302
+ logger.info({
303
+ ...providerTrace,
304
+ ...trace.metadata,
305
+ component: trace.component,
306
+ functionName: trace.functionName,
307
+ phase: "start",
308
+ message: trace.message
309
+ });
310
+ try {
311
+ let result = await handler();
312
+ let successMessage = resolveTraceMessage(trace.successMessage, result);
313
+ logger.info({
314
+ ...providerTrace,
315
+ ...trace.metadata,
316
+ ...trace.onSuccess?.(result) ?? {},
317
+ component: trace.component,
318
+ functionName: trace.functionName,
319
+ phase: "success",
320
+ durationMs: Date.now() - startedAt,
321
+ message: successMessage
322
+ });
323
+ return result;
324
+ } catch (error) {
325
+ logger.error({
326
+ ...providerTrace,
327
+ ...trace.metadata,
328
+ ...toErrorMetadata(error),
329
+ component: trace.component,
330
+ functionName: trace.functionName,
331
+ phase: "error",
332
+ durationMs: Date.now() - startedAt,
333
+ message: trace.errorMessage ?? `${typeof trace.successMessage === "string" ? trace.successMessage : trace.message} failed`
334
+ });
335
+ throw error;
336
+ }
337
+ };
338
+ let getContextBasic = () => {
339
+ let currentProtocol = protocol.get();
340
+ let currentParticipants = participants.get();
341
+ if (!currentProtocol || !currentParticipants) {
342
+ throw new ServiceError4(
343
+ preconditionFailedError({
344
+ message: "Connection context has not been initialized"
345
+ })
346
+ );
347
+ }
348
+ return {
349
+ protocol: currentProtocol,
350
+ participants: currentParticipants
351
+ };
352
+ };
353
+ let getContextFull = () => {
354
+ let basic = getContextBasic();
355
+ let currentConfig = config.get();
356
+ let currentSession = session.get();
357
+ let currentAuth = auth.get();
358
+ if (!currentConfig || !currentSession || !currentAuth && slate.spec.auth.authStack.length > 0) {
359
+ throw new ServiceError4(
360
+ preconditionFailedError({
361
+ message: "Session context has not been initialized"
362
+ })
363
+ );
364
+ }
365
+ return {
366
+ ...basic,
367
+ config: currentConfig.value,
368
+ session: currentSession,
369
+ auth: currentAuth
370
+ };
371
+ };
372
+ let getAuthConfig = () => config.get()?.value ?? {};
373
+ let getEmptyContext = () => new SlateContext({}, {}, {}, slate.spec, logger);
374
+ let getAuthContext = () => new SlateContext(getAuthConfig(), {}, {}, slate.spec, logger);
375
+ let withRequestTraces = (context, result) => {
376
+ let requestTraces = context.getHttpTraces();
377
+ return requestTraces.length > 0 ? { ...result, requestTraces } : result;
378
+ };
379
+ manager.onNotification("slates/hello", async ({ params }) => {
380
+ protocol.set(params.protocol);
381
+ });
382
+ manager.onNotification("slates/participant.set", async ({ params }) => {
383
+ if (!protocol.get()) {
384
+ throw new ServiceError4(
385
+ preconditionFailedError({ message: "Connection protocol has not been initialized" })
386
+ );
387
+ }
388
+ participants.set(params.participants);
389
+ });
390
+ manager.onNotification("slates/auth.set", async ({ params }) => {
391
+ getContextBasic();
392
+ getAuthMethod(slate, params.authenticationMethodId);
393
+ let valRes = validate(
394
+ slate.spec.authSchema,
395
+ params.output,
396
+ "auth",
397
+ `Invalid authentication output for method ID: ${params.authenticationMethodId}`
398
+ );
399
+ auth.set({
400
+ authenticationMethodId: params.authenticationMethodId,
401
+ output: valRes
402
+ });
403
+ });
404
+ manager.onNotification("slates/config.set", async ({ params }) => {
405
+ getContextBasic();
406
+ let value = validate(
407
+ slate.spec.configSchema,
408
+ params.config,
409
+ "config",
410
+ "Invalid configuration"
411
+ );
412
+ config.set({ value });
413
+ });
414
+ manager.onNotification("slates/session.start", async ({ params }) => {
415
+ getContextBasic();
416
+ session.set({
417
+ id: params.sessionId,
418
+ state: params.state
419
+ });
420
+ });
421
+ manager.onRequest("slates/config.changed", async ({ params }) => {
422
+ getContextBasic();
423
+ let newConfig = validate(
424
+ slate.spec.config.configSchema,
425
+ params.newConfig,
426
+ "config",
427
+ "Invalid configuration"
428
+ );
429
+ let configChanged = slate.spec.config.handlers.configChanged;
430
+ if (!configChanged) {
431
+ return { success: true, config: newConfig };
432
+ }
433
+ let context = getEmptyContext();
434
+ let updatedConfig = await traceProviderCall(
435
+ {
436
+ component: "config",
437
+ functionName: "configChanged",
438
+ message: "Running config change handler",
439
+ successMessage: "Config change handler completed",
440
+ metadata: {
441
+ hasPreviousConfig: params.previousConfig !== null,
442
+ newConfigKeyCount: getObjectKeyCount(newConfig)
443
+ },
444
+ onSuccess: (result) => ({
445
+ returnedConfig: !!result?.config
446
+ })
447
+ },
448
+ () => runWithContext(
449
+ context,
450
+ async () => configChanged({
451
+ previousConfig: params.previousConfig,
452
+ newConfig
453
+ })
454
+ )
455
+ );
456
+ return withRequestTraces(context, {
457
+ success: true,
458
+ config: updatedConfig?.config ?? newConfig
459
+ });
460
+ });
461
+ manager.onRequest("slates/config.get_default", async () => {
462
+ getContextBasic();
463
+ let getDefaultConfig = slate.spec.config.handlers.getDefaultConfig;
464
+ if (!getDefaultConfig) {
465
+ return { config: null };
466
+ }
467
+ let context = getEmptyContext();
468
+ let defaultConfig = await traceProviderCall(
469
+ {
470
+ component: "config",
471
+ functionName: "getDefaultConfig",
472
+ message: "Getting default config",
473
+ successMessage: "Default config retrieved",
474
+ onSuccess: (result) => ({
475
+ configKeyCount: getObjectKeyCount(result)
476
+ })
477
+ },
478
+ () => runWithContext(context, async () => getDefaultConfig())
479
+ );
480
+ return withRequestTraces(context, {
481
+ config: defaultConfig ?? null
482
+ });
483
+ });
484
+ manager.onRequest("slates/config.schema.get", async () => {
485
+ getContextBasic();
486
+ return {
487
+ schema: toJsonSchema(slate.spec.configSchema),
488
+ docs: slate.spec.config.docsReferences ?? []
489
+ };
490
+ });
491
+ manager.onRequest("slates/provider.identify", async () => {
492
+ getContextBasic();
493
+ return {
494
+ protocol: SLATES_PROTOCOL_VERSION,
495
+ provider: {
496
+ type: "provider",
497
+ id: slate.spec.key,
498
+ name: slate.spec.name,
499
+ description: slate.spec.description,
500
+ metadata: slate.spec.parameters.metadata
501
+ },
502
+ docs: slate.spec.docs ?? []
503
+ };
504
+ });
505
+ manager.onRequest("slates/auth.methods.list", async () => {
506
+ getContextBasic();
507
+ return {
508
+ authenticationMethods: slate.spec.auth.authStack.map((m) => mapAuthMethod(slate, m))
509
+ };
510
+ });
511
+ manager.onRequest("slates/auth.method.get", async ({ params }) => {
512
+ getContextBasic();
513
+ let authMethod = getAuthMethod(slate, params.authenticationMethodId);
514
+ return {
515
+ authenticationMethod: mapAuthMethod(slate, authMethod)
516
+ };
517
+ });
518
+ manager.onRequest("slates/auth.input.get_default", async ({ params }) => {
519
+ getContextBasic();
520
+ let authMethod = getAuthMethod(slate, params.authenticationMethodId);
521
+ if (!authMethod.getDefaultInput) {
522
+ return { input: null };
523
+ }
524
+ let context = getEmptyContext();
525
+ let input = await traceProviderCall(
526
+ {
527
+ component: "auth",
528
+ functionName: "getDefaultInput",
529
+ message: "Getting default authentication input",
530
+ successMessage: "Default authentication input retrieved",
531
+ metadata: {
532
+ authenticationMethodId: params.authenticationMethodId,
533
+ authenticationMethodName: authMethod.name
534
+ },
535
+ onSuccess: (result) => ({
536
+ inputKeyCount: getObjectKeyCount(result)
537
+ })
538
+ },
539
+ () => runWithContext(context, () => authMethod.getDefaultInput())
540
+ );
541
+ return withRequestTraces(context, { input });
542
+ });
543
+ manager.onRequest("slates/auth.input.changed", async ({ params }) => {
544
+ getContextBasic();
545
+ let authMethod = getAuthMethod(slate, params.authenticationMethodId);
546
+ if (!authMethod.onInputChanged) {
547
+ return { success: true, input: params.newInput };
548
+ }
549
+ let context = getEmptyContext();
550
+ let updatedInput = await traceProviderCall(
551
+ {
552
+ component: "auth",
553
+ functionName: "onInputChanged",
554
+ message: "Running authentication input change handler",
555
+ successMessage: "Authentication input change handler completed",
556
+ metadata: {
557
+ authenticationMethodId: params.authenticationMethodId,
558
+ authenticationMethodName: authMethod.name,
559
+ hasPreviousInput: params.previousInput !== null,
560
+ newInputKeyCount: getObjectKeyCount(params.newInput)
561
+ },
562
+ onSuccess: (result) => ({
563
+ returnedInput: !!result?.input
564
+ })
565
+ },
566
+ () => runWithContext(
567
+ context,
568
+ () => authMethod.onInputChanged({
569
+ previousInput: params.previousInput,
570
+ newInput: params.newInput
571
+ })
572
+ )
573
+ );
574
+ return withRequestTraces(context, {
575
+ success: true,
576
+ input: updatedInput?.input ?? params.newInput
577
+ });
578
+ });
579
+ manager.onRequest("slates/auth.output.get", async ({ params }) => {
580
+ getContextBasic();
581
+ let authMethod = getAuthMethod(slate, params.authenticationMethodId);
582
+ let input = params.input;
583
+ if (authMethod.inputSchema) {
584
+ input = validate(
585
+ authMethod.inputSchema,
586
+ input,
587
+ "auth",
588
+ `Invalid authentication input for method ID: ${params.authenticationMethodId}`
589
+ );
590
+ }
591
+ if ("getOutput" in authMethod) {
592
+ let context = getAuthContext();
593
+ let outputRes = await traceProviderCall(
594
+ {
595
+ component: "auth",
596
+ functionName: "getOutput",
597
+ message: "Getting authentication output",
598
+ successMessage: "Authentication output retrieved",
599
+ metadata: {
600
+ authenticationMethodId: params.authenticationMethodId,
601
+ authenticationMethodName: authMethod.name,
602
+ inputKeyCount: getObjectKeyCount(input)
603
+ },
604
+ onSuccess: (result) => ({
605
+ outputKeyCount: getObjectKeyCount(result.output),
606
+ scopeCount: result.scopes?.length ?? 0
607
+ })
608
+ },
609
+ () => runWithContext(
610
+ context,
611
+ () => authMethod.getOutput({
612
+ input,
613
+ config: getAuthConfig()
614
+ })
615
+ )
616
+ );
617
+ return withRequestTraces(context, {
618
+ output: outputRes.output,
619
+ scopes: outputRes.scopes
620
+ });
621
+ }
622
+ return { output: input };
623
+ });
624
+ manager.onRequest("slates/auth.authorization_callback.handle", async ({ params }) => {
625
+ getContextBasic();
626
+ let authMethod = getAuthMethod(slate, params.authenticationMethodId);
627
+ if ("handleCallback" in authMethod) {
628
+ let context = getEmptyContext();
629
+ let callbackRes = await traceProviderCall(
630
+ {
631
+ component: "auth",
632
+ functionName: "handleCallback",
633
+ message: "Handling authentication callback",
634
+ successMessage: "Authentication callback handled",
635
+ metadata: {
636
+ authenticationMethodId: params.authenticationMethodId,
637
+ authenticationMethodName: authMethod.name,
638
+ scopeCount: params.scopes.length,
639
+ hasCallbackState: !!params.callbackState
640
+ },
641
+ onSuccess: (result) => ({
642
+ outputKeyCount: getObjectKeyCount(result.output),
643
+ returnedInput: !!result.input,
644
+ returnedScopeCount: result.scopes?.length
645
+ })
646
+ },
647
+ () => runWithContext(
648
+ context,
649
+ () => authMethod.handleCallback({
650
+ code: params.code,
651
+ state: params.state,
652
+ redirectUri: params.redirectUri,
653
+ input: params.input,
654
+ clientId: params.clientId,
655
+ clientSecret: params.clientSecret,
656
+ scopes: params.scopes,
657
+ callbackParams: params.callbackParams || {},
658
+ callbackState: params.callbackState || {},
659
+ config: getAuthConfig()
660
+ })
661
+ )
662
+ );
663
+ return withRequestTraces(context, {
664
+ output: callbackRes.output,
665
+ input: callbackRes.input,
666
+ scopes: callbackRes.scopes
667
+ });
668
+ }
669
+ throw new ServiceError4(
670
+ preconditionFailedError({
671
+ message: `Authentication method does not support authorization callback handling: ${params.authenticationMethodId}`
672
+ })
673
+ );
674
+ });
675
+ manager.onRequest("slates/auth.authorization_url.get", async ({ params }) => {
676
+ getContextBasic();
677
+ let authMethod = getAuthMethod(slate, params.authenticationMethodId);
678
+ if ("getAuthorizationUrl" in authMethod) {
679
+ let context = getEmptyContext();
680
+ let urlRes = await traceProviderCall(
681
+ {
682
+ component: "auth",
683
+ functionName: "getAuthorizationUrl",
684
+ message: "Getting authentication authorization URL",
685
+ successMessage: "Authentication authorization URL retrieved",
686
+ metadata: {
687
+ authenticationMethodId: params.authenticationMethodId,
688
+ authenticationMethodName: authMethod.name,
689
+ scopeCount: params.scopes.length,
690
+ inputKeyCount: getObjectKeyCount(params.input)
691
+ },
692
+ onSuccess: (result) => ({
693
+ returnedInput: !!result.input,
694
+ hasCallbackState: !!result.callbackState
695
+ })
696
+ },
697
+ () => runWithContext(
698
+ context,
699
+ () => authMethod.getAuthorizationUrl({
700
+ redirectUri: params.redirectUri,
701
+ state: params.state,
702
+ input: params.input,
703
+ clientId: params.clientId,
704
+ clientSecret: params.clientSecret,
705
+ scopes: params.scopes,
706
+ config: getAuthConfig()
707
+ })
708
+ )
709
+ );
710
+ return withRequestTraces(context, {
711
+ authorizationUrl: urlRes.url,
712
+ input: urlRes.input,
713
+ callbackState: urlRes.callbackState
714
+ });
715
+ }
716
+ throw new ServiceError4(
717
+ preconditionFailedError({
718
+ message: `Authentication method does not support authorization URL retrieval: ${params.authenticationMethodId}`
719
+ })
720
+ );
721
+ });
722
+ manager.onRequest("slates/auth.profile.get", async ({ params }) => {
723
+ getContextBasic();
724
+ let authMethod = getAuthMethod(slate, params.authenticationMethodId);
725
+ if (authMethod.getProfile) {
726
+ let context = getAuthContext();
727
+ let profileRes = await traceProviderCall(
728
+ {
729
+ component: "auth",
730
+ functionName: "getProfile",
731
+ message: "Getting authentication profile",
732
+ successMessage: "Authentication profile retrieved",
733
+ metadata: {
734
+ authenticationMethodId: params.authenticationMethodId,
735
+ authenticationMethodName: authMethod.name,
736
+ scopeCount: params.scopes.length,
737
+ inputKeyCount: getObjectKeyCount(params.input),
738
+ outputKeyCount: getObjectKeyCount(params.output)
739
+ },
740
+ onSuccess: (result) => ({
741
+ profileKeyCount: getObjectKeyCount(result.profile)
742
+ })
743
+ },
744
+ () => runWithContext(context, () => {
745
+ if (authMethod.type === "auth.oauth") {
746
+ return authMethod.getProfile({
747
+ output: params.output,
748
+ input: params.input,
749
+ scopes: params.scopes,
750
+ config: getAuthConfig()
751
+ });
752
+ }
753
+ return authMethod.getProfile({
754
+ output: params.output,
755
+ input: params.input,
756
+ scopes: params.scopes,
757
+ config: getAuthConfig()
758
+ });
759
+ })
760
+ );
761
+ return withRequestTraces(context, {
762
+ profile: profileRes.profile
763
+ });
764
+ }
765
+ throw new ServiceError4(
766
+ preconditionFailedError({
767
+ message: `Authentication method does not support profile retrieval: ${params.authenticationMethodId}`
768
+ })
769
+ );
770
+ });
771
+ manager.onRequest("slates/auth.token_refresh.handle", async ({ params }) => {
772
+ getContextBasic();
773
+ let authMethod = getAuthMethod(slate, params.authenticationMethodId);
774
+ if ("handleTokenRefresh" in authMethod && authMethod.handleTokenRefresh) {
775
+ let context = getAuthContext();
776
+ let refreshRes = await traceProviderCall(
777
+ {
778
+ component: "auth",
779
+ functionName: "handleTokenRefresh",
780
+ message: "Refreshing authentication token",
781
+ successMessage: "Authentication token refreshed",
782
+ metadata: {
783
+ authenticationMethodId: params.authenticationMethodId,
784
+ authenticationMethodName: authMethod.name,
785
+ scopeCount: params.scopes.length,
786
+ inputKeyCount: getObjectKeyCount(params.input),
787
+ outputKeyCount: getObjectKeyCount(params.output)
788
+ },
789
+ onSuccess: (result) => ({
790
+ refreshedOutputKeyCount: getObjectKeyCount(result.output),
791
+ returnedInput: !!result.input
792
+ })
793
+ },
794
+ () => runWithContext(context, () => {
795
+ if (authMethod.type === "auth.oauth") {
796
+ return authMethod.handleTokenRefresh({
797
+ output: params.output,
798
+ input: params.input,
799
+ clientId: params.clientId,
800
+ clientSecret: params.clientSecret,
801
+ scopes: params.scopes,
802
+ config: getAuthConfig()
803
+ });
804
+ }
805
+ return authMethod.handleTokenRefresh({
806
+ output: params.output,
807
+ input: params.input,
808
+ clientId: params.clientId,
809
+ clientSecret: params.clientSecret,
810
+ scopes: params.scopes,
811
+ config: getAuthConfig()
812
+ });
813
+ })
814
+ );
815
+ return withRequestTraces(context, {
816
+ output: refreshRes.output,
817
+ input: refreshRes.input
818
+ });
819
+ }
820
+ throw new ServiceError4(
821
+ preconditionFailedError({
822
+ message: `Authentication method does not support token refresh handling: ${params.authenticationMethodId}`
823
+ })
824
+ );
825
+ });
826
+ manager.onRequest("slates/actions.list", async ({ params }) => {
827
+ getContextBasic();
828
+ let actions = params.includeAdapterActions ? slate.actions : slate.actions.filter((action) => !action.adapter);
829
+ return {
830
+ actions: actions.map((a) => mapAction(slate, a))
831
+ };
832
+ });
833
+ manager.onRequest("slates/adapters.list", async () => {
834
+ getContextBasic();
835
+ return {
836
+ adapters: slate.adapters.map(mapAdapter)
837
+ };
838
+ });
839
+ manager.onRequest("slates/adapter.get", async ({ params }) => {
840
+ getContextBasic();
841
+ let adapter = getAdapter(slate, params.adapterId);
842
+ return {
843
+ adapter: mapAdapter(adapter)
844
+ };
845
+ });
846
+ manager.onRequest("slates/action.get", async ({ params }) => {
847
+ getContextBasic();
848
+ let action = getAction(slate, params.actionId);
849
+ return {
850
+ action: mapAction(slate, action)
851
+ };
852
+ });
853
+ manager.onRequest("slates/action.tool.invoke", async ({ params }) => {
854
+ let action = getActionWithType(slate, "tool", params.actionId);
855
+ let input = validate(
856
+ action.inputSchema,
857
+ params.input,
858
+ "input",
859
+ `Invalid input for tool ID: ${params.actionId}`
860
+ );
861
+ let invoke = async (context) => {
862
+ let res = await traceProviderCall(
863
+ {
864
+ component: "action",
865
+ functionName: "handleInvocation",
866
+ message: `Starting tool ${formatEntityLabel(action.name, action.key)}`,
867
+ successMessage: `Completed tool ${formatEntityLabel(action.name, action.key)}`,
868
+ errorMessage: `Tool ${formatEntityLabel(action.name, action.key)} failed`,
869
+ metadata: {
870
+ actionId: action.key,
871
+ actionName: action.name,
872
+ actionType: action.type,
873
+ isPublic: action.isPublic,
874
+ inputKeyCount: getObjectKeyCount(input)
875
+ },
876
+ onSuccess: (result) => ({
877
+ hasMessage: !!result.message,
878
+ actionResultMessage: result.message,
879
+ outputKeyCount: getObjectKeyCount(result.output),
880
+ attachmentCount: result.attachments?.length
881
+ })
882
+ },
883
+ () => runWithContext(context, () => action.handleInvocation(context))
884
+ );
885
+ return withRequestTraces(context, {
886
+ output: res.output,
887
+ message: res.message,
888
+ attachments: mergeAttachments(res.attachments, res.output)
889
+ });
890
+ };
891
+ if (action.isPublic) {
892
+ getContextBasic();
893
+ return invoke(new SlatePublicContext(input, slate.spec, logger));
894
+ }
895
+ let ctx = getContextFull();
896
+ return invoke(
897
+ new SlateContext(ctx.config, input, ctx.auth?.output, slate.spec, logger)
898
+ );
899
+ });
900
+ manager.onRequest("slates/action.trigger.map_event", async ({ params }) => {
901
+ let ctx = getContextFull();
902
+ let action = getActionWithType(slate, "trigger", params.actionId);
903
+ let input = validate(
904
+ action.inputSchema,
905
+ params.input,
906
+ "input",
907
+ `Invalid event for trigger ID: ${params.actionId}`
908
+ );
909
+ let context = new SlateContext(ctx.config, input, ctx.auth?.output, slate.spec, logger);
910
+ let res = await traceProviderCall(
911
+ {
912
+ component: "action",
913
+ functionName: "handleEvent",
914
+ message: `Mapping event for trigger ${formatEntityLabel(action.name, action.key)}`,
915
+ successMessage: (result) => `Mapped trigger event "${result.type}" for ${formatEntityLabel(action.name, action.key)}`,
916
+ errorMessage: `Trigger ${formatEntityLabel(action.name, action.key)} failed while mapping an event`,
917
+ metadata: {
918
+ actionId: action.key,
919
+ actionName: action.name,
920
+ actionType: action.type,
921
+ inputKeyCount: getObjectKeyCount(input)
922
+ },
923
+ onSuccess: (result) => ({
924
+ eventType: result.type,
925
+ hasEventId: !!result.id,
926
+ outputKeyCount: getObjectKeyCount(result.output)
927
+ })
928
+ },
929
+ () => runWithContext(context, () => action.handleEvent(context))
930
+ );
931
+ return withRequestTraces(context, { id: res.id, type: res.type, output: res.output });
932
+ });
933
+ manager.onRequest("slates/action.trigger.poll_events", async ({ params }) => {
934
+ let ctx = getContextFull();
935
+ let action = getActionWithType(slate, "trigger", params.actionId);
936
+ if (!action.pollEvents) {
937
+ throw new ServiceError4(
938
+ badRequestError3({
939
+ message: `Trigger action does not support polling: ${params.actionId}`
940
+ })
941
+ );
942
+ }
943
+ let context = new SlateContext(
944
+ ctx.config,
945
+ { state: params.state },
946
+ ctx.auth?.output,
947
+ slate.spec,
948
+ logger
949
+ );
950
+ let res = await traceProviderCall(
951
+ {
952
+ component: "action",
953
+ functionName: "pollEvents",
954
+ message: `Polling events for trigger ${formatEntityLabel(action.name, action.key)}`,
955
+ successMessage: (result) => `Polled ${result.inputs.length} event(s) for trigger ${formatEntityLabel(action.name, action.key)}`,
956
+ errorMessage: `Trigger ${formatEntityLabel(action.name, action.key)} failed while polling events`,
957
+ metadata: {
958
+ actionId: action.key,
959
+ actionName: action.name,
960
+ actionType: action.type,
961
+ hasPreviousState: params.state !== null
962
+ },
963
+ onSuccess: (result) => ({
964
+ inputCount: result.inputs.length,
965
+ hasUpdatedState: result.updatedState !== void 0
966
+ })
967
+ },
968
+ () => runWithContext(context, () => action.pollEvents(context))
969
+ );
970
+ return withRequestTraces(context, {
971
+ inputs: res.inputs,
972
+ updatedState: res.updatedState
973
+ });
974
+ });
975
+ manager.onRequest("slates/action.trigger.webhook_handle", async ({ params }) => {
976
+ let ctx = getContextFull();
977
+ let action = getActionWithType(slate, "trigger", params.actionId);
978
+ if (!action.handleRequest) {
979
+ throw new ServiceError4(
980
+ badRequestError3({
981
+ message: `Trigger action does not support webhook requests: ${params.actionId}`
982
+ })
983
+ );
984
+ }
985
+ let req = new Request(params.url, {
986
+ method: params.method,
987
+ headers: params.headers,
988
+ body: params.body ? Uint8Array.from(atob(params.body.content), (c) => c.charCodeAt(0)) : null
989
+ });
990
+ let context = new SlateContext(
991
+ ctx.config,
992
+ {
993
+ request: req,
994
+ state: params.state,
995
+ registrationDetails: params.registrationDetails ?? null
996
+ },
997
+ ctx.auth?.output,
998
+ slate.spec,
999
+ logger
1000
+ );
1001
+ let res = await traceProviderCall(
1002
+ {
1003
+ component: "action",
1004
+ functionName: "handleRequest",
1005
+ message: `Handling webhook request for trigger ${formatEntityLabel(action.name, action.key)}`,
1006
+ successMessage: (result) => `Received ${result.inputs.length} webhook event(s) for trigger ${formatEntityLabel(action.name, action.key)}`,
1007
+ errorMessage: `Trigger ${formatEntityLabel(action.name, action.key)} failed while handling a webhook request`,
1008
+ metadata: {
1009
+ actionId: action.key,
1010
+ actionName: action.name,
1011
+ actionType: action.type,
1012
+ requestMethod: params.method,
1013
+ hasRequestBody: !!params.body,
1014
+ hasPreviousState: params.state !== null
1015
+ },
1016
+ onSuccess: (result) => ({
1017
+ inputCount: result.inputs.length,
1018
+ hasUpdatedState: result.updatedState !== void 0,
1019
+ hasResponse: result.response !== void 0
1020
+ })
1021
+ },
1022
+ () => runWithContext(context, () => action.handleRequest(context))
1023
+ );
1024
+ let response = res.response === void 0 ? void 0 : await serializeWebhookHttpResponse(res.response);
1025
+ return withRequestTraces(context, {
1026
+ inputs: res.inputs,
1027
+ updatedState: res.updatedState,
1028
+ response
1029
+ });
1030
+ });
1031
+ manager.onRequest("slates/action.trigger.webhook_register", async ({ params }) => {
1032
+ let ctx = getContextFull();
1033
+ let action = getActionWithType(slate, "trigger", params.actionId);
1034
+ if (!action.autoRegisterWebhook) {
1035
+ throw new ServiceError4(
1036
+ badRequestError3({
1037
+ message: `Trigger action does not support webhook auto-registration: ${params.actionId}`
1038
+ })
1039
+ );
1040
+ }
1041
+ let context = new SlateContext(
1042
+ ctx.config,
1043
+ { webhookBaseUrl: params.webhookBaseUrl },
1044
+ ctx.auth?.output,
1045
+ slate.spec,
1046
+ logger
1047
+ );
1048
+ let res = await traceProviderCall(
1049
+ {
1050
+ component: "action",
1051
+ functionName: "autoRegisterWebhook",
1052
+ message: `Registering webhook for trigger ${formatEntityLabel(action.name, action.key)}`,
1053
+ successMessage: `Registered webhook for trigger ${formatEntityLabel(action.name, action.key)}`,
1054
+ errorMessage: `Trigger ${formatEntityLabel(action.name, action.key)} failed while registering a webhook`,
1055
+ metadata: {
1056
+ actionId: action.key,
1057
+ actionName: action.name,
1058
+ actionType: action.type
1059
+ },
1060
+ onSuccess: (result) => ({
1061
+ hasRegistrationDetails: result.registrationDetails !== void 0,
1062
+ hasState: result.state !== void 0
1063
+ })
1064
+ },
1065
+ () => runWithContext(context, () => action.autoRegisterWebhook(context))
1066
+ );
1067
+ return withRequestTraces(context, {
1068
+ registrationDetails: res.registrationDetails,
1069
+ state: res.state
1070
+ });
1071
+ });
1072
+ manager.onRequest("slates/action.trigger.webhook_unregister", async ({ params }) => {
1073
+ let ctx = getContextFull();
1074
+ let action = getActionWithType(slate, "trigger", params.actionId);
1075
+ if (!action.autoUnregisterWebhook) {
1076
+ throw new ServiceError4(
1077
+ badRequestError3({
1078
+ message: `Trigger action does not support webhook auto-unregistration: ${params.actionId}`
1079
+ })
1080
+ );
1081
+ }
1082
+ let context = new SlateContext(
1083
+ ctx.config,
1084
+ {
1085
+ webhookBaseUrl: params.webhookBaseUrl,
1086
+ registrationDetails: params.registrationDetails,
1087
+ state: params.state
1088
+ },
1089
+ ctx.auth?.output,
1090
+ slate.spec,
1091
+ logger
1092
+ );
1093
+ await traceProviderCall(
1094
+ {
1095
+ component: "action",
1096
+ functionName: "autoUnregisterWebhook",
1097
+ message: `Unregistering webhook for trigger ${formatEntityLabel(action.name, action.key)}`,
1098
+ successMessage: `Unregistered webhook for trigger ${formatEntityLabel(action.name, action.key)}`,
1099
+ errorMessage: `Trigger ${formatEntityLabel(action.name, action.key)} failed while unregistering a webhook`,
1100
+ metadata: {
1101
+ actionId: action.key,
1102
+ actionName: action.name,
1103
+ actionType: action.type,
1104
+ hasRegistrationDetails: params.registrationDetails !== null,
1105
+ hasPreviousState: params.state !== null
1106
+ }
1107
+ },
1108
+ () => runWithContext(context, () => action.autoUnregisterWebhook(context))
1109
+ );
1110
+ return withRequestTraces(context, {});
1111
+ });
1112
+ });
1113
+ export {
1114
+ createProviderHandler
1115
+ };