experimental-ash 0.50.0 → 0.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/docs/public/advanced/instrumentation.md +87 -119
  3. package/dist/docs/public/advanced/typescript-api.md +4 -2
  4. package/dist/docs/public/channels/discord.mdx +2 -2
  5. package/dist/docs/public/channels/index.md +47 -6
  6. package/dist/docs/public/channels/teams.mdx +1 -1
  7. package/dist/docs/public/channels/telegram.mdx +2 -2
  8. package/dist/docs/public/meta.json +1 -0
  9. package/dist/docs/public/onboarding.md +119 -0
  10. package/dist/docs/public/schedules.mdx +4 -4
  11. package/dist/docs/public/tools.mdx +5 -40
  12. package/dist/src/channel/compiled-channel.d.ts +2 -2
  13. package/dist/src/channel/cross-channel-receive.d.ts +6 -6
  14. package/dist/src/channel/cross-channel-receive.js +1 -1
  15. package/dist/src/channel/receive-target.d.ts +17 -0
  16. package/dist/src/cli/commands/channels.d.ts +2 -0
  17. package/dist/src/cli/commands/channels.js +1 -1
  18. package/dist/src/cli/commands/info.d.ts +46 -1
  19. package/dist/src/cli/commands/info.js +2 -2
  20. package/dist/src/cli/run.d.ts +3 -1
  21. package/dist/src/cli/run.js +2 -2
  22. package/dist/src/execution/node-step.js +1 -1
  23. package/dist/src/harness/{instrumentation-metadata.d.ts → instrumentation-runtime-context.d.ts} +2 -2
  24. package/dist/src/harness/instrumentation-runtime-context.js +1 -0
  25. package/dist/src/harness/tool-loop.js +1 -1
  26. package/dist/src/harness/tool-result-pruning.d.ts +2 -16
  27. package/dist/src/harness/tool-result-pruning.js +1 -1
  28. package/dist/src/harness/types.d.ts +0 -9
  29. package/dist/src/internal/application/package.js +1 -1
  30. package/dist/src/internal/authored-definition/schema-backed.js +1 -1
  31. package/dist/src/internal/instrumentation.d.ts +8 -7
  32. package/dist/src/internal/instrumentation.js +1 -1
  33. package/dist/src/packages/ash-scaffold/src/channels.js +2 -2
  34. package/dist/src/packages/ash-scaffold/src/human-action.js +1 -0
  35. package/dist/src/packages/ash-scaffold/src/index.js +1 -1
  36. package/dist/src/packages/ash-scaffold/src/steps/run-add-to-agent.js +1 -1
  37. package/dist/src/packages/ash-scaffold/src/steps/setup-slackbot.js +1 -1
  38. package/dist/src/public/channels/ash.d.ts +59 -1
  39. package/dist/src/public/channels/ash.js +2 -2
  40. package/dist/src/public/channels/discord/discordChannel.d.ts +3 -3
  41. package/dist/src/public/channels/discord/discordChannel.js +1 -1
  42. package/dist/src/public/channels/discord/index.d.ts +1 -1
  43. package/dist/src/public/channels/slack/index.d.ts +1 -1
  44. package/dist/src/public/channels/slack/slackChannel.d.ts +4 -3
  45. package/dist/src/public/channels/slack/slackChannel.js +1 -1
  46. package/dist/src/public/channels/teams/index.d.ts +1 -1
  47. package/dist/src/public/channels/teams/teamsChannel.d.ts +3 -3
  48. package/dist/src/public/channels/teams/teamsChannel.js +1 -1
  49. package/dist/src/public/channels/telegram/index.d.ts +1 -1
  50. package/dist/src/public/channels/telegram/telegramChannel.d.ts +3 -3
  51. package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
  52. package/dist/src/public/channels/twilio/index.d.ts +1 -1
  53. package/dist/src/public/channels/twilio/twilioChannel.d.ts +3 -3
  54. package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
  55. package/dist/src/public/definitions/defineChannel.d.ts +8 -8
  56. package/dist/src/public/definitions/schedule.d.ts +2 -2
  57. package/dist/src/public/definitions/tool.d.ts +0 -40
  58. package/dist/src/public/instrumentation/index.d.ts +21 -11
  59. package/dist/src/public/schedules/index.d.ts +1 -1
  60. package/dist/src/public/tools/index.d.ts +1 -1
  61. package/dist/src/runtime/framework-tools/skill.js +1 -1
  62. package/dist/src/runtime/resolve-tool.d.ts +1 -1
  63. package/dist/src/runtime/resolve-tool.js +1 -1
  64. package/dist/src/runtime/types.d.ts +1 -9
  65. package/package.json +1 -1
  66. package/dist/src/channel/receive-args.d.ts +0 -17
  67. package/dist/src/harness/instrumentation-metadata.js +0 -1
  68. /package/dist/src/channel/{receive-args.js → receive-target.js} +0 -0
@@ -1 +1 @@
1
- import{createLogger}from"#internal/logging.js";import{POST,defineChannel}from"#public/definitions/defineChannel.js";import{verifyTwilioRequest}from"#public/channels/twilio/verify.js";import{callTwilioApi,sendTwilioMessage,twilioContinuationToken,updateTwilioCall}from"#public/channels/twilio/api.js";import{emptyTwilioResponse,gatherSpeechTwilioResponse,sayTwilioResponse}from"#public/channels/twilio/twiml.js";import{defaultEvents,defaultOnText,defaultOnVoice,defaultOnVoiceTranscription}from"#public/channels/twilio/defaults.js";import{formatTwilioContextBlock,parseTwilioTextMessage,parseTwilioVoiceCall,parseTwilioVoiceTranscription}from"#public/channels/twilio/inbound.js";const log=createLogger(`twilio.channel`);function twilioChannel(e){assertAllowFromConfigured(e);let r=buildRoutes(e.route??`/ash/v1/twilio`),i=e.onText??defaultOnText,a=e.onVoice??defaultOnVoice,s=e.onVoiceTranscription??defaultOnVoiceTranscription,l={...defaultEvents,...e.events};return defineChannel({kindHint:`twilio`,state:{from:null,to:null,lastCallSid:null,lastMessageSid:null},metadata(e){return{from:e.from,lastCallSid:e.lastCallSid??null,lastMessageSid:e.lastMessageSid??null,to:e.to}},context(t,n){return rebuildTwilioContext(t,n,e)},routes:[POST(r.messages,async(t,{send:n,waitUntil:r})=>{let a=await verifyInbound(t,e);if(a===null)return new Response(`unauthorized`,{status:401});let o=parseTwilioTextMessage(a.params);return o?await isAllowed(o.from,e.allowFrom)?(r(dispatchText({config:e,message:o,onText:i,send:n})),emptyTwilioResponse()):new Response(`forbidden`,{status:403}):emptyTwilioResponse()}),POST(r.voice,async t=>{let n=await verifyInbound(t,e);if(n===null)return new Response(`unauthorized`,{status:401});let i=parseTwilioVoiceCall(n.params);if(!i)return sayTwilioResponse(`Missing caller information.`);if(!await isAllowed(i.from,e.allowFrom))return new Response(`forbidden`,{status:403});let o=await acceptVoiceCall({call:i,config:e,onVoice:a});if(o===null)return new Response(`forbidden`,{status:403});let s=o??{};return gatherSpeechTwilioResponse({actionUrl:await buildActionUrl(t,e,r.transcription),hints:s.hints??e.voice?.hints,language:s.language??e.voice?.language,profanityFilter:s.profanityFilter??e.voice?.profanityFilter,prompt:s.prompt??e.voice?.prompt??`Please say your message after the tone.`,speechModel:s.speechModel??e.voice?.speechModel,speechTimeout:s.speechTimeout??e.voice?.speechTimeout??`auto`,timeoutSeconds:s.timeoutSeconds??e.voice?.timeoutSeconds,voice:s.voice??e.voice?.voice})}),POST(r.transcription,async(t,{send:n,waitUntil:i})=>{let a=await verifyInbound(t,e);if(a===null)return new Response(`unauthorized`,{status:401});let o=parseTwilioVoiceTranscription(a.params);return o?await isAllowed(o.from,e.allowFrom)?(i(dispatchVoiceTranscription({config:e,onVoiceTranscription:s,send:n,transcription:o})),sayTwilioResponse(e.voice?.acknowledgement??`Thanks. I'll follow up by text.`)):new Response(`forbidden`,{status:403}):gatherSpeechTwilioResponse({actionUrl:await buildActionUrl(t,e,r.transcription),language:e.voice?.language,prompt:e.voice?.prompt??`Please say your message after the tone.`,speechTimeout:e.voice?.speechTimeout??`auto`,timeoutSeconds:e.voice?.timeoutSeconds})})],async receive(t,{send:n}){let r=readString(t.args.phoneNumber);if(!r)throw Error(`twilioChannel().receive requires args.phoneNumber.`);let i=readString(t.args.from)??e.messaging?.from??null;return n(t.message,{auth:t.auth,continuationToken:twilioContinuationToken(r,i??void 0),state:{from:r,lastCallSid:null,lastMessageSid:null,to:i}})},events:l})}function rebuildTwilioContext(e,t,n){return{state:e,twilio:buildTwilioHandle({callSid:e.lastCallSid??void 0,config:n,from:e.from??``,to:e.to??void 0})}}function buildTwilioHandle(e){let t=e.config.api,n=e.config.credentials,r=e.config.messaging?.from??e.to,o=e.config.messaging?.messagingServiceSid,c=e.config.messaging?.statusCallbackUrl;return{callSid:e.callSid,from:e.from,to:e.to,request(e,r){return callTwilioApi({apiBaseUrl:t?.apiBaseUrl,body:r,credentials:n,fetch:t?.fetch,path:e})},sendMessage(i,s){return sendTwilioMessage({apiBaseUrl:t?.apiBaseUrl,body:i,credentials:n,fetch:t?.fetch,from:s?.from??r,messagingServiceSid:s?.messagingServiceSid??o,statusCallbackUrl:s?.statusCallbackUrl??c,to:s?.to??e.from})},updateCall(e,r){return updateTwilioCall({apiBaseUrl:t?.apiBaseUrl,callSid:e,credentials:n,fetch:t?.fetch,twiml:r})}}}function buildRoutes(e){let t=e.endsWith(`/`)?e.slice(0,-1):e;return{messages:`${t}/messages`,transcription:`${t}/voice/transcription`,voice:`${t}/voice`}}function assertAllowFromConfigured(e){if(e?.allowFrom===void 0)throw Error(`twilioChannel requires allowFrom. Use allowFrom: "*" to allow all numbers.`)}async function verifyInbound(e,t){try{return await verifyTwilioRequest(e,{authToken:t.credentials?.authToken,webhookUrl:t.webhookUrl})}catch(e){return log.warn(`twilio inbound verification failed`,{error:e}),null}}async function dispatchText(e){let{message:t}=e,n={twilio:buildTwilioHandle({callSid:void 0,config:e.config,from:t.from,to:t.to})},r;try{r=await e.onText(n,t)}catch(e){log.error(`text handler failed`,{error:e});return}if(r==null)return;let i=formatTwilioContextBlock({channel:`text`,from:t.from,messageSid:t.messageSid,to:t.to});try{await e.send({message:t.body,context:[i]},{auth:r.auth,continuationToken:twilioContinuationToken(t.from,t.to),state:{from:t.from,lastCallSid:null,lastMessageSid:t.messageSid??null,to:t.to??null}})}catch(e){log.error(`text delivery failed`,{error:e})}}async function acceptVoiceCall(e){let{call:t}=e,n={twilio:buildTwilioHandle({callSid:t.callSid,config:e.config,from:t.from,to:t.to})};try{return await e.onVoice(n,t)}catch(e){return log.error(`voice handler failed`,{error:e}),null}}async function dispatchVoiceTranscription(e){let{transcription:t}=e,n={twilio:buildTwilioHandle({callSid:t.callSid,config:e.config,from:t.from,to:t.to})},r;try{r=await e.onVoiceTranscription(n,t)}catch(e){log.error(`voice transcription handler failed`,{error:e});return}if(r==null)return;let i=formatTwilioContextBlock({callSid:t.callSid,channel:`voice`,from:t.from,to:t.to});try{await e.send({message:t.text,context:[i]},{auth:r.auth,continuationToken:twilioContinuationToken(t.from,t.to),state:{from:t.from,lastCallSid:t.callSid??null,lastMessageSid:null,to:t.to??null}})}catch(e){log.error(`voice transcription delivery failed`,{error:e})}}async function isAllowed(e,t){let n=typeof t==`function`?await t():t;return n===`*`?!0:typeof n==`string`?n===e:n.includes(e)}async function buildActionUrl(e,t,n){let r=typeof t.publicBaseUrl==`function`?await t.publicBaseUrl(e):t.publicBaseUrl;if(r)return new URL(n,ensureTrailingSlash(r)).toString();let i=new URL(e.url);return i.pathname=n,i.search=``,i.toString()}function ensureTrailingSlash(e){return e.endsWith(`/`)?e:`${e}/`}function readString(e){return typeof e==`string`&&e.length>0?e:void 0}export{twilioChannel};
1
+ import{createLogger}from"#internal/logging.js";import{POST,defineChannel}from"#public/definitions/defineChannel.js";import{verifyTwilioRequest}from"#public/channels/twilio/verify.js";import{callTwilioApi,sendTwilioMessage,twilioContinuationToken,updateTwilioCall}from"#public/channels/twilio/api.js";import{emptyTwilioResponse,gatherSpeechTwilioResponse,sayTwilioResponse}from"#public/channels/twilio/twiml.js";import{defaultEvents,defaultOnText,defaultOnVoice,defaultOnVoiceTranscription}from"#public/channels/twilio/defaults.js";import{formatTwilioContextBlock,parseTwilioTextMessage,parseTwilioVoiceCall,parseTwilioVoiceTranscription}from"#public/channels/twilio/inbound.js";const log=createLogger(`twilio.channel`);function twilioChannel(e){assertAllowFromConfigured(e);let r=buildRoutes(e.route??`/ash/v1/twilio`),i=e.onText??defaultOnText,a=e.onVoice??defaultOnVoice,s=e.onVoiceTranscription??defaultOnVoiceTranscription,l={...defaultEvents,...e.events};return defineChannel({kindHint:`twilio`,state:{from:null,to:null,lastCallSid:null,lastMessageSid:null},metadata(e){return{from:e.from,lastCallSid:e.lastCallSid??null,lastMessageSid:e.lastMessageSid??null,to:e.to}},context(t,n){return rebuildTwilioContext(t,n,e)},routes:[POST(r.messages,async(t,{send:n,waitUntil:r})=>{let a=await verifyInbound(t,e);if(a===null)return new Response(`unauthorized`,{status:401});let o=parseTwilioTextMessage(a.params);return o?await isAllowed(o.from,e.allowFrom)?(r(dispatchText({config:e,message:o,onText:i,send:n})),emptyTwilioResponse()):new Response(`forbidden`,{status:403}):emptyTwilioResponse()}),POST(r.voice,async t=>{let n=await verifyInbound(t,e);if(n===null)return new Response(`unauthorized`,{status:401});let i=parseTwilioVoiceCall(n.params);if(!i)return sayTwilioResponse(`Missing caller information.`);if(!await isAllowed(i.from,e.allowFrom))return new Response(`forbidden`,{status:403});let o=await acceptVoiceCall({call:i,config:e,onVoice:a});if(o===null)return new Response(`forbidden`,{status:403});let s=o??{};return gatherSpeechTwilioResponse({actionUrl:await buildActionUrl(t,e,r.transcription),hints:s.hints??e.voice?.hints,language:s.language??e.voice?.language,profanityFilter:s.profanityFilter??e.voice?.profanityFilter,prompt:s.prompt??e.voice?.prompt??`Please say your message after the tone.`,speechModel:s.speechModel??e.voice?.speechModel,speechTimeout:s.speechTimeout??e.voice?.speechTimeout??`auto`,timeoutSeconds:s.timeoutSeconds??e.voice?.timeoutSeconds,voice:s.voice??e.voice?.voice})}),POST(r.transcription,async(t,{send:n,waitUntil:i})=>{let a=await verifyInbound(t,e);if(a===null)return new Response(`unauthorized`,{status:401});let o=parseTwilioVoiceTranscription(a.params);return o?await isAllowed(o.from,e.allowFrom)?(i(dispatchVoiceTranscription({config:e,onVoiceTranscription:s,send:n,transcription:o})),sayTwilioResponse(e.voice?.acknowledgement??`Thanks. I'll follow up by text.`)):new Response(`forbidden`,{status:403}):gatherSpeechTwilioResponse({actionUrl:await buildActionUrl(t,e,r.transcription),language:e.voice?.language,prompt:e.voice?.prompt??`Please say your message after the tone.`,speechTimeout:e.voice?.speechTimeout??`auto`,timeoutSeconds:e.voice?.timeoutSeconds})})],async receive(t,{send:n}){let r=readString(t.target.phoneNumber);if(!r)throw Error(`twilioChannel().receive requires target.phoneNumber.`);let i=readString(t.target.from)??e.messaging?.from??null;return n(t.message,{auth:t.auth,continuationToken:twilioContinuationToken(r,i??void 0),state:{from:r,lastCallSid:null,lastMessageSid:null,to:i}})},events:l})}function rebuildTwilioContext(e,t,n){return{state:e,twilio:buildTwilioHandle({callSid:e.lastCallSid??void 0,config:n,from:e.from??``,to:e.to??void 0})}}function buildTwilioHandle(e){let t=e.config.api,n=e.config.credentials,r=e.config.messaging?.from??e.to,o=e.config.messaging?.messagingServiceSid,c=e.config.messaging?.statusCallbackUrl;return{callSid:e.callSid,from:e.from,to:e.to,request(e,r){return callTwilioApi({apiBaseUrl:t?.apiBaseUrl,body:r,credentials:n,fetch:t?.fetch,path:e})},sendMessage(i,s){return sendTwilioMessage({apiBaseUrl:t?.apiBaseUrl,body:i,credentials:n,fetch:t?.fetch,from:s?.from??r,messagingServiceSid:s?.messagingServiceSid??o,statusCallbackUrl:s?.statusCallbackUrl??c,to:s?.to??e.from})},updateCall(e,r){return updateTwilioCall({apiBaseUrl:t?.apiBaseUrl,callSid:e,credentials:n,fetch:t?.fetch,twiml:r})}}}function buildRoutes(e){let t=e.endsWith(`/`)?e.slice(0,-1):e;return{messages:`${t}/messages`,transcription:`${t}/voice/transcription`,voice:`${t}/voice`}}function assertAllowFromConfigured(e){if(e?.allowFrom===void 0)throw Error(`twilioChannel requires allowFrom. Use allowFrom: "*" to allow all numbers.`)}async function verifyInbound(e,t){try{return await verifyTwilioRequest(e,{authToken:t.credentials?.authToken,webhookUrl:t.webhookUrl})}catch(e){return log.warn(`twilio inbound verification failed`,{error:e}),null}}async function dispatchText(e){let{message:t}=e,n={twilio:buildTwilioHandle({callSid:void 0,config:e.config,from:t.from,to:t.to})},r;try{r=await e.onText(n,t)}catch(e){log.error(`text handler failed`,{error:e});return}if(r==null)return;let i=formatTwilioContextBlock({channel:`text`,from:t.from,messageSid:t.messageSid,to:t.to});try{await e.send({message:t.body,context:[i]},{auth:r.auth,continuationToken:twilioContinuationToken(t.from,t.to),state:{from:t.from,lastCallSid:null,lastMessageSid:t.messageSid??null,to:t.to??null}})}catch(e){log.error(`text delivery failed`,{error:e})}}async function acceptVoiceCall(e){let{call:t}=e,n={twilio:buildTwilioHandle({callSid:t.callSid,config:e.config,from:t.from,to:t.to})};try{return await e.onVoice(n,t)}catch(e){return log.error(`voice handler failed`,{error:e}),null}}async function dispatchVoiceTranscription(e){let{transcription:t}=e,n={twilio:buildTwilioHandle({callSid:t.callSid,config:e.config,from:t.from,to:t.to})},r;try{r=await e.onVoiceTranscription(n,t)}catch(e){log.error(`voice transcription handler failed`,{error:e});return}if(r==null)return;let i=formatTwilioContextBlock({callSid:t.callSid,channel:`voice`,from:t.from,to:t.to});try{await e.send({message:t.text,context:[i]},{auth:r.auth,continuationToken:twilioContinuationToken(t.from,t.to),state:{from:t.from,lastCallSid:t.callSid??null,lastMessageSid:null,to:t.to??null}})}catch(e){log.error(`voice transcription delivery failed`,{error:e})}}async function isAllowed(e,t){let n=typeof t==`function`?await t():t;return n===`*`?!0:typeof n==`string`?n===e:n.includes(e)}async function buildActionUrl(e,t,n){let r=typeof t.publicBaseUrl==`function`?await t.publicBaseUrl(e):t.publicBaseUrl;if(r)return new URL(n,ensureTrailingSlash(r)).toString();let i=new URL(e.url);return i.pathname=n,i.search=``,i.toString()}function ensureTrailingSlash(e){return e.endsWith(`/`)?e:`${e}/`}function readString(e){return typeof e==`string`&&e.length>0?e:void 0}export{twilioChannel};
@@ -1,6 +1,6 @@
1
1
  import type { FetchFileResult } from "#channel/adapter.js";
2
2
  import { CHANNEL_SENTINEL } from "#channel/compiled-channel.js";
3
- import type { TypedReceiveRoute } from "#channel/receive-args.js";
3
+ import type { TypedReceiveTarget } from "#channel/receive-target.js";
4
4
  import type { SessionAuthContext } from "#channel/types.js";
5
5
  import type { HandleMessageStreamEvent } from "#protocol/message.js";
6
6
  import type { SessionContext } from "#public/definitions/callback-context.js";
@@ -49,12 +49,12 @@ export interface ChannelEvents<TCtx = void> {
49
49
  * Input passed to a channel's `receive` callback when another channel or
50
50
  * schedule proactively routes a message to it.
51
51
  */
52
- export interface ReceiveInput<TReceiveArgs = Record<string, unknown>> {
52
+ export interface ReceiveInput<TReceiveTarget = Record<string, unknown>> {
53
53
  readonly message: string;
54
- readonly args: Readonly<TReceiveArgs>;
54
+ readonly target: Readonly<TReceiveTarget>;
55
55
  readonly auth: SessionAuthContext | null;
56
56
  }
57
- export interface ChannelDefinition<TState = undefined, TCtx = void, TReceiveArgs = Record<string, unknown>, TMetadata extends Record<string, unknown> = Record<string, unknown>> {
57
+ export interface ChannelDefinition<TState = undefined, TCtx = void, TReceiveTarget = Record<string, unknown>, TMetadata extends Record<string, unknown> = Record<string, unknown>> {
58
58
  readonly state?: TState;
59
59
  /**
60
60
  * Builds the per-step channel context handed to `events` and
@@ -71,7 +71,7 @@ export interface ChannelDefinition<TState = undefined, TCtx = void, TReceiveArgs
71
71
  */
72
72
  context?(state: NonNullable<TState>, session: SessionHandle): TCtx;
73
73
  readonly routes: readonly RouteDefinition<TState>[];
74
- receive?(input: ReceiveInput<TReceiveArgs>, args: {
74
+ receive?(input: ReceiveInput<TReceiveTarget>, args: {
75
75
  send: SendFn<TState>;
76
76
  }): Promise<Session>;
77
77
  readonly events?: ChannelEvents<TCtx>;
@@ -108,16 +108,16 @@ export interface ChannelDefinition<TState = undefined, TCtx = void, TReceiveArgs
108
108
  */
109
109
  readonly kindHint?: string;
110
110
  }
111
- export interface Channel<TState = undefined, TReceiveArgs = Record<string, unknown>, TMetadata extends Record<string, unknown> = Record<string, unknown>> extends TypedReceiveRoute<TReceiveArgs> {
111
+ export interface Channel<TState = undefined, TReceiveTarget = Record<string, unknown>, TMetadata extends Record<string, unknown> = Record<string, unknown>> extends TypedReceiveTarget<TReceiveTarget> {
112
112
  readonly __kind: typeof CHANNEL_SENTINEL;
113
113
  readonly [CHANNEL_METADATA_TYPE]?: TMetadata;
114
114
  readonly routes: readonly {
115
115
  method: string;
116
116
  path: string;
117
117
  }[];
118
- readonly receive?: (input: ReceiveInput<TReceiveArgs>, args: {
118
+ readonly receive?: (input: ReceiveInput<TReceiveTarget>, args: {
119
119
  send: SendFn<TState>;
120
120
  }) => Promise<Session>;
121
121
  }
122
122
  export type InferChannelMetadata<TChannel> = TChannel extends Channel<any, any, infer TMetadata> ? TMetadata : Record<string, unknown>;
123
- export declare function defineChannel<TState = undefined, TCtx = void, TReceiveArgs = Record<string, unknown>, TMetadata extends Record<string, unknown> = Record<string, unknown>>(definition: ChannelDefinition<TState, TCtx, TReceiveArgs, TMetadata>): Channel<TState, TReceiveArgs, TMetadata>;
123
+ export declare function defineChannel<TState = undefined, TCtx = void, TReceiveTarget = Record<string, unknown>, TMetadata extends Record<string, unknown> = Record<string, unknown>>(definition: ChannelDefinition<TState, TCtx, TReceiveTarget, TMetadata>): Channel<TState, TReceiveTarget, TMetadata>;
@@ -1,7 +1,7 @@
1
1
  import type { CrossChannelReceiveFn } from "#channel/cross-channel-receive.js";
2
2
  import type { SessionAuthContext } from "#channel/types.js";
3
3
  import type { ExactDefinition } from "#public/definitions/exact.js";
4
- export type { InferReceiveArgs, TypedReceiveRoute } from "#channel/receive-args.js";
4
+ export type { InferReceiveTarget, TypedReceiveTarget } from "#channel/receive-target.js";
5
5
  /**
6
6
  * Arguments handed to {@link ScheduleDefinition.run}. Tight subset of
7
7
  * `RouteHandlerArgs` — schedules can hand work off to a channel via
@@ -72,7 +72,7 @@ export type ScheduleDefinition = {
72
72
  * async run({ receive, waitUntil, appAuth }) {
73
73
  * waitUntil(receive(slack, {
74
74
  * message: "Post the daily standup summary.",
75
- * args: { channelId: "C0123ABC" },
75
+ * target: { channelId: "C0123ABC" },
76
76
  * auth: appAuth,
77
77
  * }));
78
78
  * },
@@ -40,36 +40,6 @@ export interface NeedsApprovalContext<TInput = Record<string, unknown>> {
40
40
  readonly toolName: string;
41
41
  }
42
42
  export type { ToolModelOutput } from "#shared/tool-definition.js";
43
- /**
44
- * Result returned from a {@link ToolRetentionPolicy} function.
45
- *
46
- * Always a named object — the field name carries the intent so the
47
- * pruner and readers of the policy can't confuse it with a raw output
48
- * replacement. Room exists to grow the object (token hints, placeholder
49
- * overrides) without breaking existing policies.
50
- */
51
- export interface RetentionSummary {
52
- /**
53
- * Compact text that replaces the original tool-result output in
54
- * conversation history. Should be short and information-dense; the
55
- * model reads it as prose, not as structured data.
56
- */
57
- readonly summary: string;
58
- }
59
- /**
60
- * Between-step retention policy for a tool's results.
61
- *
62
- * - `"auto"` (default): the pruning system replaces old results with
63
- * a fixed placeholder describing that the result was dropped.
64
- * - `"keep"`: the pruning system never replaces results from this tool.
65
- * - `(output) => RetentionSummary`: the pruning system calls this
66
- * function with the original tool output and substitutes the
67
- * returned `summary` text in place of the full result.
68
- *
69
- * The function runs synchronously during reactive pruning and must be
70
- * pure — no external I/O.
71
- */
72
- export type ToolRetentionPolicy<TOutput = unknown> = "auto" | "keep" | ((output: TOutput) => RetentionSummary);
73
43
  /**
74
44
  * Authored tool context. Passed as the last argument to
75
45
  * {@link ToolDefinition.execute}.
@@ -97,14 +67,6 @@ export type ToolDefinition<TInput = unknown, TOutput = unknown> = PublicToolDefi
97
67
  * - {@link once} — require approval only the first time per session
98
68
  */
99
69
  needsApproval?: (ctx: NeedsApprovalContext<ApprovalContextInput<TInput>>) => boolean;
100
- /**
101
- * Optional between-step retention policy for this tool's results.
102
- *
103
- * The function form receives the awaited return value of
104
- * {@link execute} — strongly typed as `TOutput`. See
105
- * {@link ToolRetentionPolicy}.
106
- */
107
- retentionPolicy?: ToolRetentionPolicy<TOutput>;
108
70
  /**
109
71
  * Optional projection that controls what the model sees as the tool
110
72
  * result. Receives the full `TOutput` from {@link execute} and returns
@@ -141,7 +103,6 @@ export declare function defineTool<TSchema extends StandardJSONSchemaV1<unknown,
141
103
  inputSchema: TSchema;
142
104
  execute(input: StandardJSONSchemaV1.InferOutput<TSchema>, ctx: ToolContext): Promise<TOutput> | TOutput;
143
105
  needsApproval?: ToolDefinition<StandardJSONSchemaV1.InferOutput<TSchema>, unknown>["needsApproval"];
144
- retentionPolicy?: ToolDefinition<unknown, TOutput>["retentionPolicy"];
145
106
  toModelOutput?: ToolDefinition<unknown, TOutput>["toModelOutput"];
146
107
  onCompact?: ToolDefinition<unknown, unknown>["onCompact"];
147
108
  }): ToolDefinition<StandardJSONSchemaV1.InferOutput<TSchema>, TOutput>;
@@ -150,7 +111,6 @@ export declare function defineTool<TOutput>(definition: {
150
111
  inputSchema: JsonObject;
151
112
  execute(input: Record<string, unknown>, ctx: ToolContext): Promise<TOutput> | TOutput;
152
113
  needsApproval?: ToolDefinition<Record<string, unknown>, unknown>["needsApproval"];
153
- retentionPolicy?: ToolDefinition<unknown, TOutput>["retentionPolicy"];
154
114
  toModelOutput?: ToolDefinition<unknown, TOutput>["toModelOutput"];
155
115
  onCompact?: ToolDefinition<unknown, unknown>["onCompact"];
156
116
  }): ToolDefinition<Record<string, unknown>, TOutput>;
@@ -5,6 +5,7 @@ import type { ExactDefinition } from "#public/definitions/exact.js";
5
5
  import type { ModelMessage, SystemModelMessage } from "ai";
6
6
  import type { SessionAuthContext, SessionParent } from "#channel/types.js";
7
7
  import type { Channel } from "#public/definitions/defineChannel.js";
8
+ import type { JsonObject } from "#shared/json.js";
8
9
  /**
9
10
  * Context passed to the {@link InstrumentationDefinition.setup} callback.
10
11
  */
@@ -18,12 +19,12 @@ export interface InstrumentationSetupContext {
18
19
  readonly agentName: string;
19
20
  }
20
21
  /**
21
- * User-authored metadata attached to AI SDK telemetry spans.
22
+ * User-authored runtime context values attached to AI SDK telemetry spans.
22
23
  *
23
- * Keys beginning with `ash.` are reserved for framework-owned metadata
24
+ * Keys beginning with `ash.` are reserved for framework-owned context
24
25
  * and are ignored when returned from authored instrumentation.
25
26
  */
26
- export type InstrumentationMetadata = Readonly<Record<string, string>>;
27
+ export type InstrumentationRuntimeContext = JsonObject;
27
28
  /**
28
29
  * Base channel metadata shape used by framework channel kinds.
29
30
  */
@@ -91,12 +92,12 @@ export interface InstrumentationModelInput {
91
92
  readonly messages: readonly ModelMessage[];
92
93
  }
93
94
  /**
94
- * Input passed to `metadata["step.started"]`.
95
+ * Input passed to `events["step.started"]`.
95
96
  *
96
97
  * The callback runs after Ash has built the final model input for this
97
98
  * model-call attempt and before the AI SDK model call is constructed.
98
99
  */
99
- export interface InstrumentationStepStartedMetadataInput {
100
+ export interface InstrumentationStepStartedEventInput {
100
101
  readonly channel: InstrumentationChannel;
101
102
  readonly modelInput: InstrumentationModelInput;
102
103
  readonly session: InstrumentationSession;
@@ -104,14 +105,23 @@ export interface InstrumentationStepStartedMetadataInput {
104
105
  readonly turn: InstrumentationTurn;
105
106
  }
106
107
  /**
107
- * Metadata hooks accepted by {@link defineInstrumentation}.
108
+ * Result returned by `events["step.started"]`.
108
109
  */
109
- export interface InstrumentationMetadataConfig {
110
+ export interface InstrumentationStepStartedEventResult {
110
111
  /**
111
- * Per-attempt metadata resolved before the model call so child spans
112
+ * Additional runtime context merged into AI SDK telemetry spans.
113
+ */
114
+ readonly runtimeContext: InstrumentationRuntimeContext;
115
+ }
116
+ /**
117
+ * Event hooks accepted by {@link defineInstrumentation}.
118
+ */
119
+ export interface InstrumentationEvents {
120
+ /**
121
+ * Per-attempt runtime context resolved before the model call so child spans
112
122
  * created by the AI SDK inherit the returned values.
113
123
  */
114
- readonly "step.started"?: (input: InstrumentationStepStartedMetadataInput) => InstrumentationMetadata;
124
+ readonly "step.started"?: (input: InstrumentationStepStartedEventInput) => InstrumentationStepStartedEventResult | undefined;
115
125
  }
116
126
  /**
117
127
  * Authored instrumentation settings accepted by `defineInstrumentation`.
@@ -127,9 +137,9 @@ export interface InstrumentationDefinition {
127
137
  */
128
138
  readonly functionId?: string;
129
139
  /**
130
- * Additional metadata merged into AI SDK telemetry spans.
140
+ * Instrumentation event hooks.
131
141
  */
132
- readonly metadata?: InstrumentationMetadataConfig;
142
+ readonly events?: InstrumentationEvents;
133
143
  /**
134
144
  * Whether to record full model inputs in telemetry spans.
135
145
  *
@@ -1,4 +1,4 @@
1
1
  /**
2
2
  * Schedule authoring helpers for `agent/schedules/*` files.
3
3
  */
4
- export { defineSchedule, type ScheduleDefinition, type ScheduleHandlerArgs, type ScheduleRunHandler, type TypedReceiveRoute, } from "#public/definitions/schedule.js";
4
+ export { defineSchedule, type ScheduleDefinition, type ScheduleHandlerArgs, type ScheduleRunHandler, type TypedReceiveTarget, } from "#public/definitions/schedule.js";
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Tool authoring helpers for `agent/tools/*.ts` files.
3
3
  */
4
- export { type CompactionInput, type CompactionHookResult, type DisabledToolSentinel, defineDynamic, defineTool, disableTool, isDisabledToolSentinel, type NeedsApprovalContext, type RetentionSummary, type ToolDefinition, type ToolContext, type ToolModelOutput, type ToolRetentionPolicy, } from "#public/definitions/tool.js";
4
+ export { type CompactionInput, type CompactionHookResult, type DisabledToolSentinel, defineDynamic, defineTool, disableTool, isDisabledToolSentinel, type NeedsApprovalContext, type ToolDefinition, type ToolContext, type ToolModelOutput, } from "#public/definitions/tool.js";
5
5
  export type { DynamicToolEntry, DynamicEvents, DynamicToolEvents, DynamicResolveContext, DynamicSentinel, DynamicToolSet, DynamicToolResult, } from "#shared/dynamic-tool-definition.js";
6
6
  export { type SessionContext } from "#public/definitions/callback-context.js";
7
7
  export { toolResultFrom, type MatchedConnectionResult, type MatchedToolResult, type ToolResultFromFn, } from "#public/tool-result-narrowing.js";
@@ -1 +1 @@
1
- import{SandboxKey}from"#context/keys.js";import{loadContext}from"#context/container.js";import{loadSkillFromSandbox}from"#runtime/skills/sandbox-access.js";async function executeLoadSkillTool(t){let n=loadContext().get(SandboxKey);if(n===void 0)throw Error(`The load_skill tool requires sandbox access on the runtime context. Ensure the step is running inside a managed runtime context with sandbox support.`);let{skill:r}=t;return await loadSkillFromSandbox(n,r)}const SKILL_TOOL_DEFINITION={description:[`Load the full instructions for one available skill by name or id.`,`Use this tool when the request clearly matches a listed skill description or when the user explicitly asks for that skill.`,`Loading adds the skill instructions to the current turn.`,`Choose the "skill" value from the Available skills block.`].join(` `),execute:e=>executeLoadSkillTool(e),inputSchema:{additionalProperties:!1,properties:{skill:{description:`Available skill name or id.`,type:`string`}},required:[`skill`],type:`object`},logicalPath:`ash:framework/load-skill`,name:`load_skill`,retentionPolicy:`keep`,sourceId:`ash:load-skill-tool`,sourceKind:`module`};export{SKILL_TOOL_DEFINITION};
1
+ import{SandboxKey}from"#context/keys.js";import{loadContext}from"#context/container.js";import{loadSkillFromSandbox}from"#runtime/skills/sandbox-access.js";async function executeLoadSkillTool(t){let n=loadContext().get(SandboxKey);if(n===void 0)throw Error(`The load_skill tool requires sandbox access on the runtime context. Ensure the step is running inside a managed runtime context with sandbox support.`);let{skill:r}=t;return await loadSkillFromSandbox(n,r)}const SKILL_TOOL_DEFINITION={description:[`Load the full instructions for one available skill by name or id.`,`Use this tool when the request clearly matches a listed skill description or when the user explicitly asks for that skill.`,`Loading adds the skill instructions to the current turn.`,`Choose the "skill" value from the Available skills block.`].join(` `),execute:e=>executeLoadSkillTool(e),inputSchema:{additionalProperties:!1,properties:{skill:{description:`Available skill name or id.`,type:`string`}},required:[`skill`],type:`object`},logicalPath:`ash:framework/load-skill`,name:`load_skill`,sourceId:`ash:load-skill-tool`,sourceKind:`module`};export{SKILL_TOOL_DEFINITION};
@@ -5,7 +5,7 @@ import type { ResolvedToolDefinition } from "#runtime/types.js";
5
5
  * Resolves one compiled authored tool into a runtime-owned definition
6
6
  * with live callbacks reattached from the authored module.
7
7
  *
8
- * Optional hooks (`onCompact`, `needsApproval`, `retentionPolicy`,
8
+ * Optional hooks (`onCompact`, `needsApproval`,
9
9
  * plus an optional Standard Schema `inputSchema`) are extracted when
10
10
  * declared and validated to have the expected shape; any type mismatch
11
11
  * raises a {@link ResolveAgentError} so typos surface at resolve time
@@ -1 +1 @@
1
- import{expectFunction,expectObjectRecord}from"#internal/authored-module.js";import{toErrorMessage}from"#shared/errors.js";import{ResolveAgentError,loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{registerDefinitionSource,stampDefinitionKey}from"#public/tool-result-narrowing.js";async function resolveToolDefinition(a,o,s){try{let n=expectObjectRecord(await loadResolvedModuleExport({definition:a,kindLabel:`tool`,moduleMap:o,nodeId:s}),describe(a,`to return an object`)),r={kind:`tool`,logicalPath:a.logicalPath,name:a.name},c=`tool-source:${a.sourceId}`;stampDefinitionKey(n,c),registerDefinitionSource(c,r),registerDefinitionSource(`tool:${n.description}`,r);let l=expectFunction(n.execute,describe(a,`to provide an execute function`));return{description:a.description,execute:l,exportName:a.exportName,inputSchema:a.inputSchema,logicalPath:a.logicalPath,name:a.name,sourceId:a.sourceId,sourceKind:`module`,...extractOptionalHooks(n,a)}}catch(e){throw e instanceof ResolveAgentError?e:new ResolveAgentError(`Failed to attach the tool execute function from "${a.logicalPath}": ${toErrorMessage(e)}`,{logicalPath:a.logicalPath,sourceId:a.sourceId})}}function extractOptionalHooks(t,n){let r={};t.onCompact!==void 0&&(r.onCompact=expectFunction(t.onCompact,describe(n,`to provide an onCompact function`))),t.needsApproval!==void 0&&(r.needsApproval=expectFunction(t.needsApproval,describe(n,`to provide a needsApproval function`)));let i=extractRetentionPolicy(t,n);return i!==void 0&&(r.retentionPolicy=i),t.toModelOutput!==void 0&&(r.toModelOutput=expectFunction(t.toModelOutput,describe(n,`to provide a toModelOutput function`))),t.inputSchema!==void 0&&isFlexibleSchema(t.inputSchema)&&(r.inputStandardSchema=t.inputSchema),r}function extractRetentionPolicy(e,t){let n=e.retentionPolicy;if(n!==void 0){if(n===`auto`||n===`keep`||typeof n==`function`)return n;throw new ResolveAgentError(describe(t,`to set retentionPolicy to "auto", "keep", or a function`),{logicalPath:t.logicalPath,sourceId:t.sourceId})}}function describe(e,t){return`Expected the tool export "${e.exportName??`default`}" from "${e.logicalPath}" ${t}.`}function isFlexibleSchema(e){return typeof e==`object`&&!!e&&`~standard`in e&&typeof e[`~standard`]==`object`}export{resolveToolDefinition};
1
+ import{expectFunction,expectObjectRecord}from"#internal/authored-module.js";import{toErrorMessage}from"#shared/errors.js";import{ResolveAgentError,loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{registerDefinitionSource,stampDefinitionKey}from"#public/tool-result-narrowing.js";async function resolveToolDefinition(i,a,o){try{let n=expectObjectRecord(await loadResolvedModuleExport({definition:i,kindLabel:`tool`,moduleMap:a,nodeId:o}),describe(i,`to return an object`)),r={kind:`tool`,logicalPath:i.logicalPath,name:i.name},s=`tool-source:${i.sourceId}`;stampDefinitionKey(n,s),registerDefinitionSource(s,r),registerDefinitionSource(`tool:${n.description}`,r);let c=expectFunction(n.execute,describe(i,`to provide an execute function`));return{description:i.description,execute:c,exportName:i.exportName,inputSchema:i.inputSchema,logicalPath:i.logicalPath,name:i.name,sourceId:i.sourceId,sourceKind:`module`,...extractOptionalHooks(n,i)}}catch(e){throw e instanceof ResolveAgentError?e:new ResolveAgentError(`Failed to attach the tool execute function from "${i.logicalPath}": ${toErrorMessage(e)}`,{logicalPath:i.logicalPath,sourceId:i.sourceId})}}function extractOptionalHooks(t,n){let r={};return t.onCompact!==void 0&&(r.onCompact=expectFunction(t.onCompact,describe(n,`to provide an onCompact function`))),t.needsApproval!==void 0&&(r.needsApproval=expectFunction(t.needsApproval,describe(n,`to provide a needsApproval function`))),t.toModelOutput!==void 0&&(r.toModelOutput=expectFunction(t.toModelOutput,describe(n,`to provide a toModelOutput function`))),t.inputSchema!==void 0&&isFlexibleSchema(t.inputSchema)&&(r.inputStandardSchema=t.inputSchema),r}function describe(e,t){return`Expected the tool export "${e.exportName??`default`}" from "${e.logicalPath}" ${t}.`}function isFlexibleSchema(e){return typeof e==`object`&&!!e&&`~standard`in e&&typeof e[`~standard`]==`object`}export{resolveToolDefinition};
@@ -7,7 +7,7 @@ import type { ChannelMethod, RouteContext } from "#public/definitions/channel.js
7
7
  import type { RouteHandler } from "#channel/routes.js";
8
8
  import type { OutboundAuthFn } from "#public/agents/auth.js";
9
9
  import type { StreamEventHook } from "#public/definitions/hook.js";
10
- import type { CompactionInput, CompactionHookResult, NeedsApprovalContext, ToolModelOutput, ToolRetentionPolicy } from "#public/definitions/tool.js";
10
+ import type { CompactionInput, CompactionHookResult, NeedsApprovalContext, ToolModelOutput } from "#public/definitions/tool.js";
11
11
  import type { AuthorizationDefinition, HeadersDefinition, ToolFilterDefinition } from "#runtime/connections/types.js";
12
12
  import type { CompiledWorkspaceResourceRoot } from "#compiler/manifest.js";
13
13
  import type { WorkspaceRuntimeSpec } from "#runtime/workspace/types.js";
@@ -125,14 +125,6 @@ export type ResolvedToolDefinition = Readonly<Optional<InternalToolDefinitionWit
125
125
  * than blanket.
126
126
  */
127
127
  readonly approvalKey?: (toolInput: Readonly<Record<string, unknown>>) => string;
128
- /**
129
- * Optional retention policy for old results of this tool. Controls the
130
- * behavior of the reactive pruning system when this tool's results age
131
- * outside the protection window. See {@link ToolRetentionPolicy}.
132
- *
133
- * When omitted, the default `"auto"` policy applies.
134
- */
135
- readonly retentionPolicy?: ToolRetentionPolicy;
136
128
  /**
137
129
  * Optional compaction hook. The execution layer invokes this for every
138
130
  * resolved tool that declares it after the harness compacts message
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "experimental-ash",
3
- "version": "0.50.0",
3
+ "version": "0.52.0",
4
4
  "bin": {
5
5
  "ash": "./bin/ash.js",
6
6
  "experimental-ash": "./bin/ash.js"
@@ -1,17 +0,0 @@
1
- declare const receiveArgsMarker: unique symbol;
2
- /**
3
- * Structural marker attached by channel factories (e.g. `slackChannel`,
4
- * `twilioChannel`) to advertise the args type their `receive()` accepts.
5
- * `receive(channel, args)` helpers and the route-handler
6
- * `args.receive(channel, ...)` use this marker to infer typed args
7
- * from a plain channel import.
8
- */
9
- export interface TypedReceiveRoute<TArgs = Record<string, unknown>> {
10
- readonly [receiveArgsMarker]?: TArgs;
11
- }
12
- /**
13
- * Extracts the receive-args type from a channel value, falling back to
14
- * `Record<string, unknown>` when the channel does not advertise one.
15
- */
16
- export type InferReceiveArgs<TChannel> = TChannel extends TypedReceiveRoute<infer TArgs> ? TArgs : Record<string, unknown>;
17
- export {};
@@ -1 +0,0 @@
1
- import{createLogger,formatError}from"#internal/logging.js";import{normalizeInstrumentationChannelKind,resolveInstrumentationProjection}from"#internal/instrumentation.js";import{AuthKey,ChannelInstrumentationKey,InitiatorAuthKey,ParentSessionKey}from"#context/keys.js";import{parseJsonValue}from"#shared/json.js";import{contextStorage}from"#context/container.js";const log=createLogger(`harness.instrumentation-metadata`);function buildTelemetryRuntimeContext(e){if(e.authored===void 0)return;let t=resolveStepStartedMetadata(e),r=contextStorage.getStore()?.get(ChannelInstrumentationKey);return{...t,"ash.channel.kind":normalizeInstrumentationChannelKind(r?.kind),"ash.environment":e.environment,"ash.session.id":e.session.sessionId,"ash.step.index":String(e.emissionState.stepIndex),"ash.turn.id":e.emissionState.turnId,"ash.turn.sequence":String(e.emissionState.sequence),"ash.version":e.ashVersion}}function buildInstrumentationStepStartedInput(e){let t=contextStorage.getStore(),r=t?.get(ChannelInstrumentationKey);return{channel:{kind:normalizeInstrumentationChannelKind(r?.kind),metadata:snapshotForInstrumentation(r?.metadata,`channel.metadata`)??{}},modelInput:snapshotForInstrumentation(e.modelInput,`modelInput`)??{instructions:void 0,messages:[]},session:{auth:projectSessionAuth(t),id:e.session.sessionId,parent:snapshotForInstrumentation(t?.get(ParentSessionKey),`session.parent`)},step:{index:e.emissionState.stepIndex},turn:{id:e.emissionState.turnId,sequence:e.emissionState.sequence}}}function filterAuthoredMetadata(e,t){let n={};for(let[r,i]of Object.entries(e)){if(r.startsWith(`ash.`)){log.warn(`ignoring reserved instrumentation metadata key`,{key:r,source:t});continue}if(typeof i!=`string`){log.warn(`ignoring non-string instrumentation metadata value`,{key:r,source:t,valueType:typeof i});continue}n[r]=i}return Object.keys(n).length>0?n:void 0}function resolveStepStartedMetadata(e){let t=e.authored?.metadata?.[`step.started`];if(t===void 0)return;let n=`metadata["step.started"]`,i=resolveInstrumentationProjection({invoke:()=>t(buildInstrumentationStepStartedInput(e)),log,source:n});return i===void 0?void 0:filterAuthoredMetadata(i,n)}function projectSessionAuth(e){let t=e?.get(AuthKey)??null,n=e?.get(InitiatorAuthKey)??t;return{current:snapshotForInstrumentation(t,`session.auth.current`)??null,initiator:snapshotForInstrumentation(n,`session.auth.initiator`)??null}}function snapshotForInstrumentation(e,n){if(e!==void 0)try{return parseJsonValue(e)}catch(e){log.warn(`dropping non-serializable instrumentation snapshot`,{error:formatError(e),source:n});return}}export{buildTelemetryRuntimeContext};