eve 0.79.2 → 0.80.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/dist/src/compiled/.vendor-stamp.json +8 -8
- package/dist/src/compiled/@chat-adapter/slack/api.d.ts +6 -0
- package/dist/src/compiled/@chat-adapter/slack/api.js +1 -1
- package/dist/src/compiled/@chat-adapter/slack/blocks.js +1 -1
- package/dist/src/compiled/@chat-adapter/slack/format.js +1 -1
- package/dist/src/compiled/@chat-adapter/slack/index.d.ts +14 -8
- package/dist/src/compiled/@chat-adapter/slack/index.js +33 -32
- package/dist/src/compiled/@chat-adapter/twilio/index.d.ts +37 -1
- package/dist/src/compiled/@chat-adapter/twilio/index.js +2 -2
- package/dist/src/compiled/@linqapp/chat-sdk-adapter/index.js +1 -1
- package/dist/src/compiled/@photon-ai/chat-adapter-imessage/index.js +1 -1
- package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/adapters/ai-sdk-telemetry.d.ts +2 -2
- package/dist/src/compiled/{@eve/tracing/agent-tracing.d.ts → @vercel/agent-runs/agent-run.d.ts} +3 -3
- package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/index.d.ts +1 -1
- package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/index.js +1 -1
- package/dist/src/compiled/@vercel/connect/index.js +5 -5
- package/dist/src/compiled/@vercel/connect/token.d.ts +11 -1
- package/dist/src/compiled/@workflow/world-vercel/index.js +3 -3
- package/dist/src/compiled/_chunks/node/chunk-NBSLXVG3-Bt7pDfyn.js +12 -0
- package/dist/src/compiled/_chunks/node/dist-BKsV21Vu.js +6 -0
- package/dist/src/compiled/_chunks/node/dist-CO_n_hUa.js +98 -0
- package/dist/src/compiled/chat/index.js +1 -1
- package/dist/src/compiler/extension-compatibility.d.ts +6 -6
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/compiler/manifest.d.ts +8 -4
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/compiler/normalize-connection.js +1 -1
- package/dist/src/compiler/normalize-manifest.js +1 -1
- package/dist/src/context/schedule-collection-tools.js +1 -1
- package/dist/src/execution/catalog/connection-auth.d.ts +4 -2
- package/dist/src/execution/catalog/connection-auth.js +1 -1
- package/dist/src/execution/catalog/connection-entry.js +1 -1
- package/dist/src/execution/dynamic-workflow/tool.js +1 -1
- package/dist/src/execution/session/entry.js +1 -1
- package/dist/src/execution/session-event-stream.js +1 -1
- package/dist/src/execution/stable-workflow-names.d.ts +2 -0
- package/dist/src/execution/stable-workflow-names.js +1 -1
- package/dist/src/execution/tools/agent-router-workflow.js +1 -1
- package/dist/src/execution/web-fetch/execute.js +1 -1
- package/dist/src/execution/workflow-runtime.d.ts +6 -0
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/extensions/git/extension/extension.d.ts +3 -1
- package/dist/src/extensions/git/extension/extension.js +1 -1
- package/dist/src/extensions/git/extension/lib/gh-tool.js +1 -1
- package/dist/src/extensions/git/extension/lib/github-shell.d.ts +14 -0
- package/dist/src/extensions/git/extension/lib/github-shell.js +1 -1
- package/dist/src/harness/compaction/engine.js +2 -2
- package/dist/src/harness/compaction/prompt.d.ts +6 -0
- package/dist/src/harness/compaction/prompt.js +1 -1
- package/dist/src/harness/model-call/call.js +1 -1
- package/dist/src/harness/model-call/errors.d.ts +2 -2
- package/dist/src/harness/model-call/recovery.d.ts +2 -3
- package/dist/src/instrumentation/ai-sdk-hook-bridge.js +1 -1
- package/dist/src/instrumentation/principal-summary.js +1 -1
- package/dist/src/instrumentation/runtime.d.ts +1 -1
- package/dist/src/instrumentation/runtime.js +1 -1
- package/dist/src/instrumentation/session-init.d.ts +2 -1
- package/dist/src/instrumentation/session-init.js +1 -1
- package/dist/src/internal/application/stamped-package-version.js +1 -1
- package/dist/src/internal/authored-definition/connection.js +1 -1
- package/dist/src/internal/authored-definition/schedule-collection.js +1 -1
- package/dist/src/internal/authored-package-boundary.d.ts +4 -0
- package/dist/src/internal/authored-package-boundary.js +1 -1
- package/dist/src/internal/bundler/nitro-rolldown.d.ts +2 -2
- package/dist/src/internal/logging.js +1 -1
- package/dist/src/internal/nitro/host/application-route-registry.d.ts +7 -2
- package/dist/src/internal/nitro/host/application-route-registry.js +1 -1
- package/dist/src/internal/nitro/host/configure-nitro-routes.js +1 -1
- package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
- package/dist/src/internal/nitro/host/external-dependency-output-check-plugin.d.ts +23 -0
- package/dist/src/internal/nitro/host/external-dependency-output-check-plugin.js +3 -0
- package/dist/src/internal/nitro/routes/channel-request-instrumentation.d.ts +3 -1
- package/dist/src/internal/nitro/routes/channel-request-instrumentation.js +1 -1
- package/dist/src/internal/nitro/routes/connection-events.d.ts +5 -0
- package/dist/src/internal/nitro/routes/connection-events.js +1 -0
- package/dist/src/internal/workflow-bundle/builder.js +1 -1
- package/dist/src/internal/workflow-bundle/dynamic-tool-ast-references.js +1 -1
- package/dist/src/public/channels/slack/blocks.js +2 -2
- package/dist/src/public/connections/index.d.ts +1 -0
- package/dist/src/public/definitions/connections/events.d.ts +43 -0
- package/dist/src/public/definitions/connections/events.js +1 -0
- package/dist/src/public/definitions/connections/mcp.d.ts +3 -0
- package/dist/src/public/schedules/subscription.d.ts +4 -3
- package/dist/src/runtime/connections/events/actions.d.ts +17 -0
- package/dist/src/runtime/connections/events/actions.js +1 -0
- package/dist/src/runtime/connections/events/delivery.d.ts +10 -0
- package/dist/src/runtime/connections/events/delivery.js +1 -0
- package/dist/src/runtime/connections/events/dispatch-step.d.ts +20 -0
- package/dist/src/runtime/connections/events/dispatch-step.js +1 -0
- package/dist/src/runtime/connections/events/lifecycle-step.d.ts +42 -0
- package/dist/src/runtime/connections/events/lifecycle-step.js +1 -0
- package/dist/src/runtime/connections/events/owner.d.ts +38 -0
- package/dist/src/runtime/connections/events/owner.js +1 -0
- package/dist/src/runtime/connections/events/path.d.ts +4 -0
- package/dist/src/runtime/connections/events/path.js +1 -0
- package/dist/src/runtime/connections/events/state.d.ts +37 -0
- package/dist/src/runtime/connections/events/state.js +1 -0
- package/dist/src/runtime/connections/events/workflow.d.ts +28 -0
- package/dist/src/runtime/connections/events/workflow.js +1 -0
- package/dist/src/runtime/connections/mcp-client.d.ts +4 -2
- package/dist/src/runtime/connections/mcp-client.js +1 -1
- package/dist/src/runtime/connections/openapi-client.js +1 -1
- package/dist/src/runtime/connections/scoped-authorization.js +1 -1
- package/dist/src/runtime/resolve-connection.js +1 -1
- package/dist/src/runtime/schedules/collection-client.d.ts +0 -2
- package/dist/src/runtime/schedules/collection-client.js +1 -1
- package/dist/src/runtime/types.d.ts +11 -0
- package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +2 -2
- package/dist/src/setup/scaffold/update/channels.js +1 -1
- package/dist/src/setup/scaffold/update/connections.js +2 -2
- package/dist/src/setup/scaffold/version-tokens.d.ts +1 -1
- package/dist/src/setup/scaffold/version-tokens.js +1 -1
- package/dist/src/shared/agent-definition.d.ts +12 -4
- package/dist/src/shared/connection-events.d.ts +84 -0
- package/dist/src/shared/connection-events.js +1 -0
- package/dist/src/shared/connection-types.d.ts +10 -0
- package/dist/src/shared/validate-authorization.js +1 -1
- package/dist/src/tools/provided/ask-question-workflow.js +1 -1
- package/dist/src/tools/provided/no-reply.d.ts +5 -0
- package/dist/src/tools/provided/sleep-workflow.js +1 -1
- package/dist/src/tracing/eve/agent-approval-instrumentation.d.ts +2 -2
- package/dist/src/tracing/eve/agent-channel-delivery-instrumentation.js +1 -1
- package/dist/src/tracing/eve/agent-memory-instrumentation.d.ts +2 -2
- package/dist/src/tracing/eve/agent-memory-instrumentation.js +1 -1
- package/dist/src/tracing/eve/agent-otel-provider.d.ts +1 -1
- package/dist/src/tracing/eve/agent-tool-instrumentation.d.ts +3 -3
- package/dist/src/tracing/eve/agent-trace-context.js +1 -1
- package/dist/src/tracing/eve/agent-trace-state.d.ts +1 -1
- package/dist/src/tracing/eve/connection-events.d.ts +25 -0
- package/dist/src/tracing/eve/connection-events.js +1 -0
- package/dist/src/tracing/eve/content-span-processor.js +1 -1
- package/dist/src/tracing/eve/delegation.js +1 -1
- package/dist/src/tracing/eve/gateway.d.ts +1 -1
- package/dist/src/tracing/eve/install-instrumentation-runtime.js +1 -1
- package/dist/src/tracing/eve/invoke-tool-span.js +1 -1
- package/dist/src/tracing/eve/mcp.d.ts +2 -1
- package/dist/src/tracing/eve/mcp.js +1 -1
- package/dist/src/tracing/eve/metadata.d.ts +1 -1
- package/dist/src/tracing/eve/operation-input.d.ts +2 -2
- package/dist/src/tracing/eve/operation-input.js +1 -1
- package/dist/src/tracing/eve/otel-declaration.d.ts +5 -0
- package/dist/src/tracing/eve/otel-registration.d.ts +2 -2
- package/dist/src/tracing/eve/otel-registration.js +1 -1
- package/dist/src/tracing/eve/profile.d.ts +1 -1
- package/dist/src/tracing/eve/session.d.ts +2 -2
- package/dist/src/tracing/local/trace-summary.js +1 -1
- package/docs/agent-config.md +38 -13
- package/docs/code-extension.mdx +28 -0
- package/docs/concepts/built-in-tools.md +2 -0
- package/docs/connections/mcp.mdx +105 -0
- package/docs/connections/openapi.mdx +2 -0
- package/docs/guides/instrumentation/otel.mdx +10 -0
- package/docs/sandbox/vercel.mdx +46 -0
- package/package.json +8 -8
- package/dist/src/compiled/_chunks/node/chunk-6QHBXN7B-gl4n6nmi.js +0 -12
- package/dist/src/compiled/_chunks/node/dist-DYDVZ-FS.js +0 -98
- package/dist/src/compiled/_chunks/node/dist-iEFkK9qw.js +0 -6
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/adapters/agent-transport.d.ts +0 -0
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/adapters/ai-sdk-payload.d.ts +0 -0
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/adapters/otel-error.d.ts +0 -0
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/adapters/otel-ids.d.ts +0 -0
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/adapters/otel.d.ts +0 -0
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/adapters/serialization.d.ts +0 -0
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/ai-sdk.d.ts +0 -0
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/ai-sdk.js +0 -0
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/capture.d.ts +0 -0
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/core/activation.d.ts +0 -0
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/core/attributes.d.ts +0 -0
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/core/content-policy.d.ts +0 -0
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/core/context.d.ts +0 -0
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/core/delegation.d.ts +0 -0
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/core/mcp.d.ts +0 -0
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/core/scopes.d.ts +0 -0
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/core/snapshot.d.ts +0 -0
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/core/span-kinds.d.ts +0 -0
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/core/types.d.ts +0 -0
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/core/writer.d.ts +0 -0
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/delegation.d.ts +0 -0
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/delegation.js +0 -0
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/operations.d.ts +0 -0
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/otel.d.ts +0 -0
- /package/dist/src/compiled/{@eve/tracing → @vercel/agent-runs}/otel.js +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createHash}from"node:crypto";import{getWorkflowMetadata,getWritable}from"#compiled/@workflow/core/index.js";import{deserializeContext}from"#context/serialize.js";import{readHttpStatus}from"#runtime/connections/mcp-client.js";import{connectionEventDestination}from"#runtime/connections/events/path.js";import{withConnectionEventSpan}from"#tracing/eve/connection-events.js";import{startConnectionEventDeliveryRun}from"#runtime/connections/events/owner.js";import{CONNECTION_EVENT_SUBSCRIPTION_NAMESPACE}from"#runtime/connections/events/state.js";import{resolveBinding}from"#runtime/connections/events/dispatch-step.js";async function openConnectionEventStep(e){"use step";let t=createHash(`sha256`).update(JSON.stringify([e.binding.id,getWorkflowMetadata().workflowRunId])).digest(`hex`),n=await subscribeConnectionEvent(e.serializedContext,e.binding,t);return await publishOutcome(n),n}async function subscribeConnectionEvent(e,t,n){let r=await deserializeContext(e),i=resolveBinding(r,t);if(i===void 0)return{error:`This connection no longer accepts the subscription's binding.`};let{connection:a}=i;try{let e=await withConnectionEventSpan({ctx:r,connectionName:a.connectionName,bindingId:t.id,operation:`subscribe`},async()=>(await createAdapter(i)).subscribe({...t.request,idempotencyKey:n,options:{timeout:3e4}}));return{subscription:structuredClone(e)}}catch(e){let t=readHttpStatus(e);if(t===void 0||!isRefusal(t))throw e;return{error:e instanceof Error?e.message:String(e),status:t}}}async function unsubscribeConnectionEventStep(e){"use step";let t=await deserializeContext(e.serializedContext),n=resolveBinding(t,e.binding);if(n===void 0)return`pending`;try{return(await withConnectionEventSpan({ctx:t,connectionName:n.connection.connectionName,bindingId:e.binding.id,subscriptionId:e.subscriptionId,operation:`unsubscribe`},async()=>(await createAdapter(n)).unsubscribe({id:e.subscriptionId,options:{timeout:3e4}}))).cleanupStatus===`pending`?`pending`:`done`}catch(e){let t=readHttpStatus(e);return t===404||t===410?`done`:`pending`}}async function startConnectionEventDeliveryStep(e){"use step";await startConnectionEventDeliveryRun(e)}function createAdapter({connection:e,principal:t,events:n}){return n.backend.createAdapter({principal:t,connection:{url:e.url},destination:{path:connectionEventDestination(e.connectionName)}})}function isRefusal(e){return e>=400&&e<500&&e!==408&&e!==429}async function publishConnectionEventOutcomeStep(e){"use step";await publishOutcome(e)}async function publishOutcome(e){let t=getWritable({namespace:CONNECTION_EVENT_SUBSCRIPTION_NAMESPACE}).getWriter();try{await t.write(e)}finally{t.releaseLock()}}export{openConnectionEventStep,publishConnectionEventOutcomeStep,startConnectionEventDeliveryStep,subscribeConnectionEvent,unsubscribeConnectionEventStep};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type CompiledBundle } from "#runtime/sessions/runtime-context-keys.js";
|
|
2
|
+
import type { ConnectionEventPayload } from "#runtime/connections/events/delivery.js";
|
|
3
|
+
import { type ConnectionEventSubscribeResult, type EventBinding } from "#runtime/connections/events/state.js";
|
|
4
|
+
import type { ManagedEventSubscription } from "#shared/connection-events.js";
|
|
5
|
+
/**
|
|
6
|
+
* Starts the watch's run, which subscribes once its hook is registered. A
|
|
7
|
+
* watch already running under the binding's id answers instead. Returns
|
|
8
|
+
* undefined when the subscription is still being created after the caller
|
|
9
|
+
* stops waiting: asking for the same watch again finds it.
|
|
10
|
+
*/
|
|
11
|
+
export declare function startConnectionEventOwner(binding: EventBinding, bundle: CompiledBundle, signal?: AbortSignal): Promise<ManagedEventSubscription | undefined>;
|
|
12
|
+
/**
|
|
13
|
+
* Routes one verified delivery to its watch. Returns false when the watch
|
|
14
|
+
* has ended or never created this subscription, so the receiver tells
|
|
15
|
+
* Connect to stop. A delivery that beats the subscribe response waits in the
|
|
16
|
+
* watch's own hook, and the watch's run starts it once it knows its
|
|
17
|
+
* subscription.
|
|
18
|
+
*/
|
|
19
|
+
export declare function startConnectionEventDelivery(payload: ConnectionEventPayload, bundle: CompiledBundle): Promise<boolean>;
|
|
20
|
+
/** Runs one delivery's callback in its own short run. */
|
|
21
|
+
export declare function startConnectionEventDeliveryRun(input: {
|
|
22
|
+
readonly binding: EventBinding;
|
|
23
|
+
readonly serializedContext: Record<string, unknown>;
|
|
24
|
+
readonly payload: ConnectionEventPayload;
|
|
25
|
+
}): Promise<void>;
|
|
26
|
+
/** Connect's refusal reaches the caller with its status, so a 401 is classified as a sign-in request. */
|
|
27
|
+
export declare function subscriptionFromOutcome(outcome: ConnectionEventSubscribeResult): ManagedEventSubscription;
|
|
28
|
+
/**
|
|
29
|
+
* A running watch: who owns it and what it subscribed to. The subscription
|
|
30
|
+
* is undefined while it is still being created. An ended watch's hook ended
|
|
31
|
+
* with its run, so it is not found.
|
|
32
|
+
*/
|
|
33
|
+
export declare function findConnectionEventOwner(bindingId: string): Promise<{
|
|
34
|
+
owner: EventBinding;
|
|
35
|
+
subscription: ManagedEventSubscription | undefined;
|
|
36
|
+
} | undefined>;
|
|
37
|
+
/** Asks the watch's run to unsubscribe and end; the run repeats unsubscribe until Connect finishes. */
|
|
38
|
+
export declare function retireConnectionEventOwner(bindingId: string): Promise<boolean>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ContextContainer}from"#context/container.js";import{AuthKey,SessionIdKey,SessionTraceSeedKey}from"#context/keys.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{getHookByToken,getRun,resumeHook}from"#internal/workflow/runtime.js";import{connectionEventDeliveryWorkflowReference,connectionEventWorkflowReference,startWorkflowOnCurrentDeployment}from"#execution/workflow-runtime.js";import{serializeContext}from"#context/serialize.js";import{HookNotFoundError}from"#compiled/@workflow/errors/index.js";import{connectionEventHookToken}from"#runtime/connections/events/path.js";import{CONNECTION_EVENT_SUBSCRIPTION_NAMESPACE}from"#runtime/connections/events/state.js";function bindingContext(e,t){let n=new ContextContainer({localDevRequest:void 0});return n.set(BundleKey,t),n.set(AuthKey,e.auth),e.traceSeed!==void 0&&n.set(SessionTraceSeedKey,e.traceSeed),n.set(SessionIdKey,e.sessionId),serializeContext(n)}async function startConnectionEventOwner(e,t,n){let r=await readSubscribeOutcome((await startWorkflowOnCurrentDeployment(connectionEventWorkflowReference,[{binding:e,serializedContext:bindingContext(e,t)}])).runId,n);return r&&subscriptionFromOutcome(r)}async function startConnectionEventDelivery(e,t){let n=await findConnectionEventOwner(e.bindingId);if(n===void 0)return!1;if(n.subscription===void 0)return resumeWatch(e.bindingId,{kind:`delivery`,payload:e});if(n.subscription.id!==e.delivery.subscriptionId)return!1;let r=n.owner;return await startConnectionEventDeliveryRun({binding:r,serializedContext:bindingContext(r,t),payload:e}),!0}async function startConnectionEventDeliveryRun(e){await startWorkflowOnCurrentDeployment(connectionEventDeliveryWorkflowReference,[e])}function subscriptionFromOutcome(e){if(`error`in e)throw Object.assign(Error(e.error),{status:e.status});return e.subscription}async function findConnectionEventOwner(e){let t;try{t=await getHookByToken(connectionEventHookToken(e))}catch(e){if(HookNotFoundError.is(e))return;throw e}let n=await readPublishedOutcomeNow(t.runId);if(n===void 0||`subscription`in n)return{owner:await t.metadata,subscription:n?.subscription}}async function retireConnectionEventOwner(e){return resumeWatch(e,{kind:`retire`})}async function resumeWatch(e,t){try{return await resumeHook(connectionEventHookToken(e),t),!0}catch(e){if(HookNotFoundError.is(e))return!1;throw e}}async function readSubscribeOutcome(e,t){let n=await readPublishedOutcome(e,t);if(n===void 0||!(`ownerRunId`in n))return n;let r=await readPublishedOutcome(n.ownerRunId,t);if(r!==void 0&&`ownerRunId`in r)throw Error(`Event handler ownership did not resolve.`);return r}async function readPublishedOutcomeNow(e){let t=getRun(e).getReadable({namespace:CONNECTION_EVENT_SUBSCRIPTION_NAMESPACE}),n=await t.getTailIndex();return await t.cancel().catch(()=>{}),n<0?void 0:readPublishedOutcome(e)}async function readPublishedOutcome(e,t){let n=getRun(e).getReadable({namespace:CONNECTION_EVENT_SUBSCRIPTION_NAMESPACE}).getReader(),r=AbortSignal.any([AbortSignal.timeout(9e4),...t===void 0?[]:[t]]),i=new Promise(e=>{let abort=()=>e({value:void 0,abandoned:!0});r.aborted?abort():r.addEventListener(`abort`,abort,{once:!0})});try{let e=await Promise.race([n.read(),i]);if(`abandoned`in e)return;if(e.value===void 0)throw Error(`Event handler ended before subscribing.`);return e.value}finally{await n.cancel().catch(()=>{})}}export{findConnectionEventOwner,retireConnectionEventOwner,startConnectionEventDelivery,startConnectionEventDeliveryRun,startConnectionEventOwner,subscriptionFromOutcome};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function connectionEventRoute(connectionName: string): string;
|
|
2
|
+
export declare function connectionEventDestination(connectionName: string): string;
|
|
3
|
+
/** The watch run's hook: the receiver finds it by the binding id Connect echoes in context. */
|
|
4
|
+
export declare function connectionEventHookToken(bindingId: string): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";import{joinEveRoutePath}from"#shared/eve-route-path.js";import{EVE_PUBLIC_ROUTE_PREFIX_ENV,normalizePublicRoutePrefix}from"#shared/public-route-prefix.js";function connectionEventRoute(e){return`${EVE_ROUTE_PREFIX}/hooks/${encodeURIComponent(e)}`}function connectionEventDestination(e){return joinEveRoutePath(normalizePublicRoutePrefix(process.env[EVE_PUBLIC_ROUTE_PREFIX_ENV])??``,connectionEventRoute(e))}function connectionEventHookToken(e){return`eve:connection-event:${e}`}export{connectionEventDestination,connectionEventHookToken,connectionEventRoute};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { SessionAuthContext } from "#channel/types.js";
|
|
2
|
+
import type { SessionTraceSeed } from "#context/keys.js";
|
|
3
|
+
import type { ManagedEventSubscribeInput, ManagedEventSubscription } from "#shared/connection-events.js";
|
|
4
|
+
/** Who owns a watch. The handler's hook carries it so management can authorize callers. */
|
|
5
|
+
export type EventOwner = {
|
|
6
|
+
readonly connectionName: string;
|
|
7
|
+
readonly instanceId: string | undefined;
|
|
8
|
+
readonly connector: string;
|
|
9
|
+
readonly principalKey: string;
|
|
10
|
+
readonly executionPrincipal: string;
|
|
11
|
+
};
|
|
12
|
+
/** The handler run's input: everything a delivery needs, saved before subscribing. */
|
|
13
|
+
export interface EventBinding extends EventOwner {
|
|
14
|
+
readonly id: string;
|
|
15
|
+
readonly sessionId: string;
|
|
16
|
+
readonly auth: SessionAuthContext | null;
|
|
17
|
+
readonly traceSeed?: SessionTraceSeed;
|
|
18
|
+
/** The watch's own run adds the idempotency key, so each run subscribes once. */
|
|
19
|
+
readonly request: Omit<ManagedEventSubscribeInput, "idempotencyKey" | "options">;
|
|
20
|
+
}
|
|
21
|
+
/** The run publishes its subscription once, so callers outside it can read what it owns. */
|
|
22
|
+
export declare const CONNECTION_EVENT_SUBSCRIPTION_NAMESPACE = "eve.connection-event.subscription";
|
|
23
|
+
/** What a run's own subscribe produced. */
|
|
24
|
+
export type ConnectionEventSubscribeResult = {
|
|
25
|
+
readonly subscription: ManagedEventSubscription;
|
|
26
|
+
}
|
|
27
|
+
/** Connect refused the subscription; `status` keeps its HTTP status, such as a 401 that asks for sign-in. */
|
|
28
|
+
| {
|
|
29
|
+
readonly error: string;
|
|
30
|
+
readonly status?: number;
|
|
31
|
+
};
|
|
32
|
+
export type ConnectionEventSubscribeOutcome = ConnectionEventSubscribeResult
|
|
33
|
+
/** Another run already owns this binding: read the outcome from that run. */
|
|
34
|
+
| {
|
|
35
|
+
readonly ownerRunId: string;
|
|
36
|
+
};
|
|
37
|
+
export declare function sameEventOwner(left: EventOwner, right: EventOwner): boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const CONNECTION_EVENT_SUBSCRIPTION_NAMESPACE=`eve.connection-event.subscription`;function sameEventOwner(e,t){return e.connectionName===t.connectionName&&e.instanceId===t.instanceId&&e.connector===t.connector&&e.principalKey===t.principalKey&&e.executionPrincipal===t.executionPrincipal}export{CONNECTION_EVENT_SUBSCRIPTION_NAMESPACE,sameEventOwner};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ConnectionEventPayload } from "#runtime/connections/events/delivery.js";
|
|
2
|
+
import type { EventBinding } from "#runtime/connections/events/state.js";
|
|
3
|
+
export type ConnectionEventWatchMessage = {
|
|
4
|
+
readonly kind: "retire";
|
|
5
|
+
}
|
|
6
|
+
/** A delivery that reached the receiver before this run published its subscription. */
|
|
7
|
+
| {
|
|
8
|
+
readonly kind: "delivery";
|
|
9
|
+
readonly payload: ConnectionEventPayload;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Holds one watch: its hook carries the binding every delivery runs under,
|
|
13
|
+
* and the run waits until the watch is stopped, terminated or expires.
|
|
14
|
+
* Deliveries run in their own {@link connectionEventDeliveryWorkflow}, so
|
|
15
|
+
* this run's log only grows by the deliveries that arrive before its
|
|
16
|
+
* subscribe response does. The hook ends with the run: an ended watch is
|
|
17
|
+
* not found.
|
|
18
|
+
*/
|
|
19
|
+
export declare function connectionEventWorkflow(input: {
|
|
20
|
+
readonly binding: EventBinding;
|
|
21
|
+
readonly serializedContext: Record<string, unknown>;
|
|
22
|
+
}): Promise<void>;
|
|
23
|
+
/** Runs one delivery's callback in its own short run. */
|
|
24
|
+
export declare function connectionEventDeliveryWorkflow(input: {
|
|
25
|
+
readonly binding: EventBinding;
|
|
26
|
+
readonly serializedContext: Record<string, unknown>;
|
|
27
|
+
readonly payload: ConnectionEventPayload;
|
|
28
|
+
}): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{parseJsonObject}from"#shared/json.js";import{createHook,sleep}from"#compiled/@workflow/core/index.js";import{claimHookOwnership,disposeHook,isHookConflictError}from"#execution/hook-ownership.js";import{connectionEventHookToken}from"#runtime/connections/events/path.js";import{dispatchConnectionEventStep}from"#runtime/connections/events/dispatch-step.js";import{openConnectionEventStep,publishConnectionEventOutcomeStep,startConnectionEventDeliveryStep,unsubscribeConnectionEventStep}from"#runtime/connections/events/lifecycle-step.js";async function connectionEventWorkflow(e){"use workflow";let{binding:t,serializedContext:n}=e,r=createHook({token:connectionEventHookToken(t.id),metadata:parseJsonObject(t)});try{await claimHookOwnership(r)}catch(e){if(!isHookConflictError(e)||typeof e.conflictingRunId!=`string`)throw e;await publishConnectionEventOutcomeStep({ownerRunId:e.conflictingRunId});return}let i=await openConnectionEventStep({serializedContext:n,binding:t});if(`error`in i){await disposeHook(r);return}let{id:a,expiresAt:o}=i.subscription,s=o===null?void 0:sleep(new Date(o));for(;;){let e=await(s===void 0?r:Promise.race([r,s]));if(e===void 0)return;if(e.kind===`retire`)break;e.payload.delivery.subscriptionId===a&&await startConnectionEventDeliveryStep({binding:t,serializedContext:n,payload:e.payload})}let c=5e3;for(;await unsubscribeConnectionEventStep({serializedContext:n,binding:t,subscriptionId:a})===`pending`;)await sleep(c),c=Math.min(c*2,36e5)}async function connectionEventDeliveryWorkflow(e){"use workflow";await dispatchConnectionEventStep(e)}connectionEventWorkflow.workflowId=`workflow//eve//connectionEventWorkflow`,connectionEventDeliveryWorkflow.workflowId=`workflow//eve//connectionEventDeliveryWorkflow`;export{connectionEventDeliveryWorkflow,connectionEventWorkflow};
|
|
@@ -15,6 +15,7 @@ import type { ConnectionClient, ConnectionToolExecuteOptions, ConnectionToolMeta
|
|
|
15
15
|
*/
|
|
16
16
|
export declare class McpConnectionClient implements ConnectionClient {
|
|
17
17
|
#private;
|
|
18
|
+
readonly eventActions: ConnectionClient["eventActions"];
|
|
18
19
|
constructor(connection: ResolvedConnectionDefinition);
|
|
19
20
|
/**
|
|
20
21
|
* Connects to the MCP server, trying Streamable HTTP first and
|
|
@@ -25,8 +26,8 @@ export declare class McpConnectionClient implements ConnectionClient {
|
|
|
25
26
|
*/
|
|
26
27
|
connect(): Promise<MCPClient>;
|
|
27
28
|
/**
|
|
28
|
-
* Returns cached tool metadata for all tools this connection exposes
|
|
29
|
-
*
|
|
29
|
+
* Returns cached tool metadata for all tools this connection exposes. The
|
|
30
|
+
* catalog applies the connection's tool filter to the listing.
|
|
30
31
|
*
|
|
31
32
|
* The first call fetches tools from the server via `listTools()` and
|
|
32
33
|
* creates the AI SDK tool set in parallel. Subsequent calls return
|
|
@@ -66,6 +67,7 @@ export declare const MCP_WWW_AUTHENTICATE_META_KEY = "mcp/www_authenticate";
|
|
|
66
67
|
* tools without failing the whole HTTP request.
|
|
67
68
|
*/
|
|
68
69
|
export declare function isMcpAuthChallengeResult(result: unknown): boolean;
|
|
70
|
+
export declare function readHttpStatus(error: unknown): number | undefined;
|
|
69
71
|
/**
|
|
70
72
|
* Returns `true` when a tool name passes the configured filter.
|
|
71
73
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isObject}from"#shared/guards.js";import{buildCallbackContext}from"#context/build-callback-context.js";import{ConnectionAuthorizationRequiredError,isConnectionAuthorizationRequiredError}from"#connections/errors.js";import{resolveConnectionAuthorization}from"#runtime/connections/resolve-authorization.js";import{evictScopedToken,resolveScopedToken}from"#runtime/connections/scoped-authorization.js";import{FORWARDED_PRINCIPAL_HEADER,encodeForwardedPrincipalHeader}from"#internal/mcp/forwarded-principal-header.js";import{createMCPClient}from"#compiled/@ai-sdk/mcp/index.js";import{
|
|
1
|
+
import{isObject}from"#shared/guards.js";import{buildCallbackContext}from"#context/build-callback-context.js";import{ConnectionAuthorizationRequiredError,isConnectionAuthorizationRequiredError}from"#connections/errors.js";import{resolveConnectionAuthorization}from"#runtime/connections/resolve-authorization.js";import{evictScopedToken,resolveScopedToken}from"#runtime/connections/scoped-authorization.js";import{FORWARDED_PRINCIPAL_HEADER,encodeForwardedPrincipalHeader}from"#internal/mcp/forwarded-principal-header.js";import{createMcpTraceFetch,withMcpToolCallSpan,withMcpToolsListSpan}from"#runtime/connections/mcp-tracing.js";import{createMCPClient}from"#compiled/@ai-sdk/mcp/index.js";import{ConnectionEventActions,isEventAction}from"#runtime/connections/events/actions.js";import{readTurnPrincipals}from"#context/turn-principals.js";import{omitProvidedArgumentsFromSchema,resolveProvidedArguments}from"#runtime/connections/provided-arguments.js";var McpConnectionClient=class{#e;#t;#n;#r;#i;#a=!1;eventActions;constructor(e){if(this.#i=e,e.experimental_events!==void 0){let t=new ConnectionEventActions(e,e.experimental_events,()=>resolveHeaders(e),this.#s());this.eventActions={ownsName:isEventAction,recoveryMetadata:()=>t.recoveryMetadata(),metadata:async()=>{try{return await t.metadata()}catch(e){return await this.#d(e)}},execute:async(e,n,r)=>{try{return await t.execute(e,n,r)}catch(e){return await this.#d(e)}}}}}async connect(){if(this.#t!==void 0)return this.#t;if(this.#e!==void 0)return this.#e;this.#e=this.#o();try{return this.#t=await this.#e,this.#t}catch(e){throw this.#e=void 0,e}}async#o(){let{anonymous:e,headers:t}=await resolveConnectionHeaders(this.#i,{anonymousWhenAuthorizationRequired:!0});this.#a=e;let n=this.#i.url,r=createMcpTraceFetch({connectionName:this.#i.connectionName,fetcher:this.#s(),getProtocolVersion:()=>this.#t?.initializeResult?.protocolVersion});try{return await createMCPClient({protocolVersionDiscovery:this.#i.protocolVersionDiscovery,transport:{fetch:r,headers:t,type:`http`,url:n}})}catch(e){if(!isMcpHttpFallbackRetryableError(e))throw e;return await createMCPClient({protocolVersionDiscovery:this.#i.protocolVersionDiscovery,transport:{fetch:r,headers:t,type:`sse`,url:n}})}}#s(){if(this.#i.forwardPrincipal!==!0)return;let e=this.#i.connectionName;return async(t,n)=>{let r=readTurnPrincipals();if(r===void 0)return await globalThis.fetch(t,n);let i=new Headers(n?.headers);return i.set(FORWARDED_PRINCIPAL_HEADER,encodeForwardedPrincipalHeader(r,e)),await globalThis.fetch(t,{...n,headers:i,redirect:`error`})}}async getToolMetadata(){return(await this.#c()).metadata}async executeTool(e,t,n){let r;try{let{tools:i}=await this.#c(),a=i[e];if(a?.execute===void 0)throw Error(`Tool "${e}" not found in connection "${this.#i.connectionName}".`);let o=a.execute,s=await resolveProvidedArguments({args:t,callId:n.callId,connection:this.#i,toolName:e});r=await withMcpToolCallSpan({arguments:t,connectionName:this.#i.connectionName,execute:async()=>await o(s,{abortSignal:n.abortSignal}),protocolVersion:this.#t?.initializeResult?.protocolVersion,toolName:e})}catch(e){return await this.#d(e)}return isMcpAuthChallengeResult(r)?await this.#f(`the server asked for sign-in to call "${e}"`):r}async#c(){if(this.#r!==void 0)return this.#r;if(this.#n!==void 0)return this.#n;this.#n=this.#l();try{return this.#r=await this.#n,this.#r}catch(e){throw this.#n=void 0,e}}async#l(){try{return await this.#u()}catch(e){return await this.#d(e)}}async#u(){let e=await this.connect(),t=await withMcpToolsListSpan({connectionName:this.#i.connectionName,execute:()=>e.listTools(),protocolVersion:e.initializeResult?.protocolVersion}),n=Object.keys(this.#i.toolCall?.providedArguments??{}),r=t.tools.map(e=>({...e,inputSchema:omitProvidedArgumentsFromSchema(e.inputSchema,n)})),i=e.toolsFromDefinitions({tools:r});return{metadata:r.map(e=>({annotations:e.annotations,description:e.description??``,inputSchema:e.inputSchema??{},name:e.name,outputSchema:`outputSchema`in e&&e.outputSchema!==void 0?e.outputSchema:void 0})),tools:i}}async close(){this.#t!==void 0&&(await this.#t.close(),this.#t=void 0),this.#e=void 0,this.#n=void 0,this.#r=void 0,this.#a=!1}async#d(e){if(!isMcpAuthRequiredError(e))throw e;return await this.#f(this.#a?`the server requires sign-in`:`the server rejected the token`)}async#f(e){throw this.#a||await this.#p(),await this.close(),new ConnectionAuthorizationRequiredError(this.#i.connectionName,{message:`Connection "${this.#i.connectionName}" requires authorization (${e}).`})}async#p(){let e=await resolveConnectionAuthorization(this.#i);e!==void 0&&await evictScopedToken({authorization:e,connection:{url:this.#i.url},instanceId:this.#i.instanceId,scope:this.#i.connectionName})}};function isMcpAuthRequiredError(e){return readHttpStatus(e)===401}const MCP_WWW_AUTHENTICATE_META_KEY=`mcp/www_authenticate`;function isMcpAuthChallengeResult(e){if(!isObject(e)||e.isError!==!0||!isObject(e._meta))return!1;let t=e._meta[MCP_WWW_AUTHENTICATE_META_KEY];return(typeof t==`string`||Array.isArray(t))&&t.length>0}function isMcpHttpFallbackRetryableError(e){let t=readHttpStatus(e);return t===400||t===404||t===405}function readHttpStatus(e){for(let t of walkErrorChain(e)){if(!isObject(t))continue;let e=readStatusField(t);if(e!==void 0)return e;let n=t.response;if(isObject(n)){let e=readStatusField(n);if(e!==void 0)return e}if(typeof t.message==`string`){let e=/\bHTTP\s+(\d{3})\b/u.exec(t.message);if(e?.[1]!==void 0)return Number(e[1])}}}function readStatusField(e){if(typeof e.status==`number`)return e.status;if(typeof e.statusCode==`number`)return e.statusCode}function*walkErrorChain(e){let t=e,n=new Set;for(;t!=null&&!n.has(t);){if(n.add(t),yield t,!isObject(t)||!(`cause`in t))return;t=t.cause}}function passesToolFilter(e,t){return t===void 0?!0:`allow`in t?t.allow.includes(e):!t.block.includes(e)}async function resolveHeaders(e){let{headers:t}=await resolveConnectionHeaders(e,{anonymousWhenAuthorizationRequired:!1});return t}async function resolveConnectionHeaders(e,t){let n={},r=!1,i,getCallbackContext=()=>i??=buildCallbackContext(),a=await resolveConnectionAuthorization(e,typeof e.authorization==`function`?getCallbackContext():void 0);if(a!==void 0)try{n.Authorization=`Bearer ${(await resolveToken(e,a)).token}`}catch(e){if(!t.anonymousWhenAuthorizationRequired||!isConnectionAuthorizationRequiredError(e))throw e;r=!0}if(e.headers!==void 0){let t=await resolveHeadersDefinition(e.headers,getCallbackContext);for(let[r,i]of Object.entries(t)){if(a!==void 0&&r.toLowerCase()===`authorization`)throw Error(`Connection "${e.connectionName}" headers must not include an "Authorization" key when "authorization" is also provided.`);n[r]=i}}return{anonymous:r,headers:n}}async function resolveToken(e,t){return await resolveScopedToken({authorization:t,connection:{url:e.url},instanceId:e.instanceId,scope:e.connectionName})}async function resolveHeadersDefinition(e,t){if(typeof e==`function`)return{...await e(t())};let n={},r=Object.entries(e);for(let[e,i]of r)n[e]=await resolveHeaderValue(i,t);return n}async function resolveHeaderValue(e,t){return typeof e==`function`?await e(t()):await e}export{MCP_WWW_AUTHENTICATE_META_KEY,McpConnectionClient,isMcpAuthChallengeResult,isMcpAuthRequiredError,passesToolFilter,readHttpStatus,resolveHeaders};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";import{isObject}from"#shared/guards.js";import{isLoopbackHostname}from"#shared/network-address.js";import{parseJsonObject}from"#shared/json.js";import{
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{isObject}from"#shared/guards.js";import{isLoopbackHostname}from"#shared/network-address.js";import{parseJsonObject}from"#shared/json.js";import{resolveHeaders}from"#runtime/connections/mcp-client.js";import{omitProvidedArgumentsFromSchema,resolveProvidedArguments}from"#runtime/connections/provided-arguments.js";import{HTTP_METHODS,operationDescription,operationName,uniqueName}from"#runtime/connections/openapi-operations.js";import{buildInputSchema,deref,derefSchema,isArray}from"#runtime/connections/openapi-schema.js";import{applySecurity,resolveSecurity}from"#runtime/connections/openapi-security.js";import{extractServerUrl,parseSpecDocument}from"#runtime/connections/openapi-spec.js";const log=createLogger(`runtime.connections.openapi-client`),SWAGGER_PARAMETER_SCHEMA_KEYS=[`default`,`enum`,`exclusiveMaximum`,`exclusiveMinimum`,`format`,`items`,`maximum`,`maxItems`,`maxLength`,`minimum`,`minItems`,`minLength`,`multipleOf`,`pattern`,`type`,`uniqueItems`];var OpenApiConnectionClient=class{#e;#t;#n;constructor(e){this.#n=e}async connect(){return this.#r()}async getToolMetadata(){return(await this.#r()).metadata}async executeTool(e,t,n){let r=await this.#r(),i=r.operations.get(e);if(i===void 0)throw Error(`Tool "${e}" not found in connection "${this.#n.connectionName}".`);return this.#f(i,r.baseUrl,isObject(t)?t:{},{abortSignal:n.abortSignal,callId:n.callId})}async close(){this.#e=void 0,this.#t=void 0}async#r(){if(this.#t!==void 0)return this.#t;if(this.#e!==void 0)return this.#e;this.#e=this.#i();try{return this.#t=await this.#e,this.#t}catch(e){throw this.#e=void 0,e}}async#i(){let e=await this.#o(),t=this.#a(e),n=this.#s(e),r=[],i=new Map,a=Object.keys(this.#n.toolCall?.providedArguments??{});for(let e of n){let t;try{t=parseJsonObject(omitProvidedArgumentsFromSchema(e.inputSchema,a))}catch(t){log.warn(`omitting OpenAPI operation with an invalid input schema`,{connectionName:this.#n.connectionName,error:t,toolName:e.toolName});continue}i.set(e.toolName,e),r.push({description:e.description,inputSchema:t,name:e.toolName})}return{metadata:r,operations:i,baseUrl:t}}#a(e){let t=this.#n.url,n=typeof t==`string`&&t.trim().length>0?t:extractServerUrl(e,this.#n.spec);if(n===void 0)throw Error(`OpenAPI connection "${this.#n.connectionName}" has no base URL: set "baseUrl" or ensure the document declares an absolute "servers" entry or Swagger "host".`);return assertSecureUrl(n,this.#n.connectionName,`base`),n}async#o(){let e=this.#n.spec;if(e===void 0)throw Error(`OpenAPI connection "${this.#n.connectionName}" is missing its "spec" source.`);if(typeof e!=`string`)return e;assertSecureUrl(e,this.#n.connectionName,`spec`);let t;try{t=await fetch(e,{headers:{accept:`application/json, application/yaml, text/yaml, */*`}})}catch(t){throw Error(`OpenAPI connection "${this.#n.connectionName}" failed to fetch its spec from "${e}": ${String(t)}`)}if(t.redirected&&assertSecureUrl(t.url,this.#n.connectionName,`spec`),!t.ok)throw Error(`OpenAPI connection "${this.#n.connectionName}" failed to fetch its spec from "${e}": HTTP ${t.status}.`);let n=await t.text(),r;try{r=parseSpecDocument(n)}catch(t){throw Error(`OpenAPI connection "${this.#n.connectionName}" spec at "${e}" could not be parsed as JSON or YAML: ${String(t)}`)}if(!isObject(r))throw Error(`OpenAPI connection "${this.#n.connectionName}" spec at "${e}" is not an OpenAPI document object.`);return r}#s(e){let t=e.paths;if(!isObject(t))return[];let n=[],r=new Set;for(let[i,a]of Object.entries(t)){if(!isObject(a))continue;let t=isArray(a.parameters)?a.parameters:[];for(let o of HTTP_METHODS){let s=a[o];if(!isObject(s))continue;let c=uniqueName(operationName(s,o,i),r),l=isArray(s.parameters)?s.parameters:[],u=[...t,...l],d=this.#c(e,u),f=this.#l(e,s.requestBody,u);n.push({toolName:c,method:o,pathTemplate:i,description:operationDescription(s),parameters:d,requestBody:f,inputSchema:buildInputSchema(d,f),security:resolveSecurity(e,s)})}}return n}#c(e,t){let n=[];for(let r of t){let t=isObject(r)?deref(e,r):r;if(!isObject(t))continue;let i=t.in;if(i!==`path`&&i!==`query`&&i!==`header`&&i!==`cookie`||typeof t.name!=`string`)continue;let a=this.#u(e,t);n.push({name:t.name,location:i,required:t.required===!0||i===`path`,schema:a,description:typeof t.description==`string`?t.description:void 0})}return n}#l(e,t,n=[]){if(isObject(t)){let n=deref(e,t);if(isObject(n)&&isObject(n.content)){let t=n.content,r=`application/json`in t?`application/json`:Object.keys(t)[0];if(r!==void 0){let i=t[r],a=isObject(i)&&isObject(i.schema)?derefSchema(e,i.schema):{};return{required:n.required===!0,contentType:r,schema:a}}}}return this.#d(e,n)}#u(e,t){if(isObject(t.schema))return derefSchema(e,t.schema);let n={};for(let e of SWAGGER_PARAMETER_SCHEMA_KEYS)t[e]!==void 0&&(n[e]=t[e]);return derefSchema(e,n)}#d(e,t){for(let n of t){let t=isObject(n)?deref(e,n):n;if(!isObject(t)||t.in!==`body`)continue;let r=isObject(t.schema)?derefSchema(e,t.schema):{};return{required:t.required===!0,contentType:`application/json`,schema:r}}}async#f(e,t,n,r){let i=await resolveProvidedArguments({args:n,callId:r.callId,connection:this.#n,toolName:e.toolName}),a=await resolveHeaders(this.#n),o=e.pathTemplate,s=new URLSearchParams,c=[];for(let t of e.parameters){let n=i[t.name];if(n!=null){if(t.location===`path`){let r=String(n);if(r===`.`||r===`..`)throw Error(`Path parameter "${t.name}" for tool "${e.toolName}" in connection "${this.#n.connectionName}" must not be "." or "..".`);o=o.replace(`{${t.name}}`,encodeURIComponent(r))}else t.location===`query`?appendQuery(s,t.name,n):t.location===`cookie`?c.push(`${t.name}=${encodeURIComponent(String(n))}`):a[t.name]=String(n)}}if(applySecurity(e.security,this.#n,a,s,c),c.length>0){let e=a.cookie??a.Cookie;delete a.Cookie,a.cookie=[e,...c].filter(e=>!!e).join(`; `)}let l=new URL(joinPath(t,o));l.search=s.toString();let u;e.requestBody!==void 0&&i.body!==void 0&&(u=JSON.stringify(i.body),a[`content-type`]=e.requestBody.contentType);let d=await fetch(l,{method:e.method.toUpperCase(),headers:a,body:u,signal:r?.abortSignal});return{status:d.status,statusText:d.statusText,body:await readResponseBody(d)}}};function appendQuery(e,t,n){if(isArray(n)){for(let r of n)e.append(t,String(r));return}e.append(t,String(n))}function joinPath(e,t){return`${e.endsWith(`/`)?e.slice(0,-1):e}${t.startsWith(`/`)?t:`/${t}`}`}function assertSecureUrl(e,t,n){let r;try{r=new URL(e)}catch{throw Error(`OpenAPI connection "${t}" has an invalid ${n} URL "${e}".`)}if(r.protocol!==`https:`&&!(r.protocol===`http:`&&isLoopbackHostname(r.hostname)))throw Error(`OpenAPI connection "${t}" must use https for its ${n} (got "${r.protocol}//${r.host}").`)}async function readResponseBody(e){let t=await e.text();if(t.length===0)return null;if((e.headers.get(`content-type`)??``).includes(`application/json`))try{return JSON.parse(t)}catch{return t}return t}export{OpenApiConnectionClient};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{contextStorage,loadContext}from"#context/container.js";import{AuthKey}from"#context/keys.js";import{ConnectionAuthorizationFailedError,ConnectionAuthorizationRequiredError,isConnectionAuthorizationRequiredError}from"#connections/errors.js";import{consumeAuthorizationResult,createAuthorizationAttempt,requestAuthorization}from"#harness/authorization.js";import{supportsInteractiveAuthorization}from"#shared/connection-types.js";import{isAsyncIterable}from"#shared/async-iterable.js";import{
|
|
1
|
+
import{contextStorage,loadContext}from"#context/container.js";import{AuthKey}from"#context/keys.js";import{ConnectionAuthorizationFailedError,ConnectionAuthorizationRequiredError,isConnectionAuthorizationRequiredError}from"#connections/errors.js";import{consumeAuthorizationResult,createAuthorizationAttempt,requestAuthorization}from"#harness/authorization.js";import{supportsInteractiveAuthorization}from"#shared/connection-types.js";import{isAsyncIterable}from"#shared/async-iterable.js";import{principalKey,resolveConnectionPrincipal,resolveConnectionPrincipalFromAuth}from"#runtime/connections/principal.js";import{evictCachedToken,readCachedToken,writeCachedToken}from"#runtime/connections/authorization-tokens.js";const LOCAL_HTTP_VERCEL_CONNECT_HOSTNAMES=new Set([`127.0.0.1`,`[::1]`]);function createAuthorizationExecution(e={}){let t=new Set;async function complete(n){let r=n.instanceId??n.scope;!t.has(r)&&await(e.completeAuthorization??completeScopedAuthorization)(n)&&t.add(r)}function requireAuth(e,n){throw new ScopedAuthorizationRequiredError(e,t.has(e.instanceId??e.scope),n)}return{complete,isJustAuthorized(e){return t.has(e.instanceId??e.scope)},async getToken(e){await complete(e);try{return await resolveScopedToken(e)}catch(t){if(!isConnectionAuthorizationRequiredError(t))throw t;return requireAuth(e,t)}},async getResponderToken(e){try{return await resolveScopedToken(e)}catch(t){throw isConnectionAuthorizationRequiredError(t)?new ConnectionAuthorizationFailedError(e.scope,{message:`The approver of "${e.scope}" has no token for this provider, and an approved call doesn't start a sign-in.`,reason:`approver_authorization_required`,retryable:!1}):t}},requireAuth,async handleError(e,n){return n!==void 0&&isConnectionAuthorizationRequiredError(e)?await handleAuthorizationError(new ScopedAuthorizationRequiredError(n,t.has(n.instanceId??n.scope),e),{evictToken:!1}):await handleAuthorizationError(e)},run:executeWithAuthorization}}var ScopedAuthorizationRequiredError=class extends Error{scoped;justAuthorized;constructor(e,t,n){super(`Authorization required.`,{cause:n}),this.name=`ScopedAuthorizationRequiredError`,this.scoped=e,this.justAuthorized=t}};function isScopedAuthorizationRequiredError(e){return e instanceof Error&&e.name===`ScopedAuthorizationRequiredError`}async function handleAuthorizationError(e,t={evictToken:!0}){if(!isScopedAuthorizationRequiredError(e))throw e;let{scoped:n}=e;if(e.justAuthorized)throw new ConnectionAuthorizationFailedError(n.scope,{message:`Authorization for "${n.scope}" failed: the service rejected the token immediately after authorization.`,reason:`token_rejected_after_authorization`,retryable:!1});t.evictToken&&await evictScopedToken(n);let r=await startScopedAuthorization(n);if(r!==void 0)return r;throw supportsInteractiveAuthorization(n.authorization)?new ConnectionAuthorizationFailedError(n.scope,{message:`Authorization for "${n.scope}" requires sign-in, but no authorization callback URL could be minted for this run (missing session context).`,reason:`authorization_callback_unavailable`,retryable:!1}):e.cause??new ConnectionAuthorizationRequiredError(n.scope)}function executeWithAuthorization(e){try{let t=e();return isAsyncIterable(t)?handleIterable(t):Promise.resolve(t).catch(handleAuthorizationError)}catch(e){return handleAuthorizationError(e)}}async function*handleIterable(e){try{for await(let t of e)yield t}catch(e){yield await handleAuthorizationError(e)}}async function resolveScopedToken(e){let{scope:t,authorization:n,connection:r}=e,i=e.instanceId??t,a=contextStorage.getStore(),o=resolveScopedPrincipal(e,a);if(a===void 0)return await n.getToken({connection:r,principal:o});let s=principalKey(o),c=readCachedToken(a,i,s);if(c!==void 0)return c;let l=await n.getToken({connection:r,principal:o});return writeCachedToken(a,i,s,l),l}async function evictScopedToken(e){let{scope:t,authorization:n,connection:r}=e,i=e.instanceId??t,a=contextStorage.getStore();if(a===void 0)return;let o;try{o=resolveScopedPrincipal(e,a),evictCachedToken(a,i,principalKey(o))}catch{return}try{await n.evict?.({connection:r,principal:o})}catch{}}async function completeScopedAuthorization(e){let{scope:t,authorization:n,connection:r}=e;if(!supportsInteractiveAuthorization(n))return!1;let i=consumeAuthorizationResult(t,e.instanceId);if(i===void 0)return!1;let a=n,o=loadContext(),s=i.principal??resolveScopedPrincipal(e,o),c=await a.completeAuthorization({callbackUrl:i.hookUrl,connection:r,principal:s,resume:i.resume,callback:i.callback});return writeCachedToken(o,e.instanceId??t,principalKey(s),c),!0}async function startScopedAuthorization(e){let{scope:t,authorization:n,connection:r}=e;if(!supportsInteractiveAuthorization(n))return;let i=createAuthorizationAttempt(t);if(i===void 0)return;let a=n,o=resolveScopedPrincipal(e),s=e.boundResponder??contextStorage.getStore()?.get(AuthKey)??void 0,c=resolveAuthorizationCallbackUrl({authorization:n,callbackUrl:i.hookUrl}),{challenge:l,resume:u}=await a.startAuthorization({callbackUrl:c,connection:r,principal:o});return requestAuthorization([{attemptId:i.attemptId,challenge:stampChallengeDisplayName(l,n),grant:n.vercelConnect?.connector,hookUrl:c,instanceId:e.instanceId,name:t,principal:o,principalId:s?.principalId,requester:s,resume:u}])}function resolveScopedPrincipal(e,t){return e.boundResponder===void 0?resolveConnectionPrincipal(e.scope,e.authorization,t):resolveConnectionPrincipalFromAuth(e.scope,e.authorization,e.boundResponder,t)}function resolveAuthorizationCallbackUrl(e){if(e.authorization.vercelConnect===void 0)return e.callbackUrl;let t;try{t=new URL(e.callbackUrl)}catch{return e.callbackUrl}return t.protocol!==`http:`||!LOCAL_HTTP_VERCEL_CONNECT_HOSTNAMES.has(t.hostname)?e.callbackUrl:(t.hostname=`localhost`,t.toString())}function stampChallengeDisplayName(e,t){let n=t.displayName??e.displayName;return n===e.displayName?e:{...e,displayName:n}}export{completeScopedAuthorization,createAuthorizationExecution,evictScopedToken,handleAuthorizationError,resolveAuthorizationCallbackUrl,resolveScopedToken,stampChallengeDisplayName};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{expectObjectRecord}from"#internal/authored-module.js";import{toErrorMessage}from"#shared/errors.js";import{normalizeMcpClientConnectionDefinition,normalizeOpenApiConnectionDefinition}from"#internal/authored-definition/connection.js";import{readStampedConnectionProtocol}from"#public/definitions/connections/protocol.js";import{connectionDefinitionKey,registerDefinitionSource}from"#internal/authored-definition/source-identity.js";import{normalizeAuthorizationSpec}from"#shared/validate-authorization.js";import{ResolveAgentError,loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{createConnectionInstanceId}from"#runtime/connections/instance-identity.js";async function resolveConnectionDefinition(e,t,n){try{let r=await loadResolvedModuleExport({definition:e,kindLabel:`connection`,moduleMap:t,nodeId:n}),i=expectObjectRecord(r,`Expected the connection export "${e.exportName??`default`}" from "${e.logicalPath}" to return an object.`);registerDefinitionSource(i,{kind:`connection`,logicalPath:e.logicalPath,name:e.connectionName},connectionDefinitionKey(e.url,e.description));let a=i.auth!==void 0,o=i.headers!==void 0,s=e.protocol===`openapi`?i.operations:i.tools,c={connectionName:e.connectionName,description:e.description,exportName:e.exportName,logicalPath:e.logicalPath,instanceId:createConnectionInstanceId({connectionName:e.connectionName,instanceKey:typeof i.instanceKey==`string`?i.instanceKey:void 0,protocol:e.protocol,sourceId:e.sourceId,url:e.url}),protocol:e.protocol,sourceId:e.sourceId,sourceKind:`module`,url:e.url};if(a){if(typeof i.auth==`function`)c.authorization=i.auth;else try{c.authorization=normalizeAuthorizationSpec(i.auth,`Connection "${e.connectionName}" at "${e.logicalPath}":`)}catch(t){throw new ResolveAgentError(toErrorMessage(t),{logicalPath:e.logicalPath,sourceId:e.sourceId})}}if(e.protocol===`mcp`&&i.protocolVersionDiscovery!==void 0){if(typeof i.protocolVersionDiscovery!=`boolean`)throw Error(`"protocolVersionDiscovery" must be a boolean.`);c.protocolVersionDiscovery=i.protocolVersionDiscovery}if(e.protocol===`mcp`&&i.forwardPrincipal!==void 0){if(typeof i.forwardPrincipal!=`boolean`)throw Error(`"forwardPrincipal" must be a boolean.`);c.forwardPrincipal=i.forwardPrincipal}return o&&(c.headers=i.headers),i.toolCall!==void 0&&(c.toolCall=i.toolCall),s!==void 0&&(c.tools=s),e.protocol===`openapi`&&i.spec!==void 0&&(c.spec=i.spec),typeof i.approval==`function`&&(c.approval=i.approval),c}catch(t){throw t instanceof ResolveAgentError?t:new ResolveAgentError(`Failed to resolve connection "${e.connectionName}" from "${e.logicalPath}": ${toErrorMessage(t)}`,{logicalPath:e.logicalPath,sourceId:e.sourceId})}}function resolveDynamicConnectionValue(e,t){let n=readStampedConnectionProtocol(e),r=`Dynamic connection "${t.connectionName}" from "${t.logicalPath}" must be created by defineMcpClientConnection() or defineOpenAPIConnection().`;if(n===void 0)throw Error(r);if(registerDefinitionSource(e,{kind:`connection`,logicalPath:t.logicalPath,name:t.connectionName}),n===`openapi`){let i=normalizeOpenApiConnectionDefinition(e,r);return assertAuthenticatedDynamicInstanceKey(i.auth,i.instanceKey,r),omitUndefined({approval:i.approval,authorization:i.auth,connectionName:t.connectionName,description:i.description,exportName:t.exportName,headers:i.headers,instanceId:createConnectionInstanceId({connectionName:t.connectionName,instanceKey:i.instanceKey,protocol:n,sourceId:t.sourceId,url:i.baseUrl??``}),logicalPath:t.logicalPath,protocol:n,sourceId:t.sourceId,sourceKind:`module`,spec:i.spec,toolCall:i.toolCall,tools:i.operations,url:i.baseUrl??``})}let i=normalizeMcpClientConnectionDefinition(e,r);return assertAuthenticatedDynamicInstanceKey(i.auth,i.instanceKey,r),omitUndefined({approval:i.approval,authorization:i.auth,connectionName:t.connectionName,description:i.description,exportName:t.exportName,headers:i.headers,instanceId:createConnectionInstanceId({connectionName:t.connectionName,instanceKey:i.instanceKey,protocol:n,sourceId:t.sourceId,url:i.url}),logicalPath:t.logicalPath,protocol:n,sourceId:t.sourceId,sourceKind:`module`,toolCall:i.toolCall,protocolVersionDiscovery:i.protocolVersionDiscovery,forwardPrincipal:i.forwardPrincipal,tools:i.tools,url:i.url})}function assertAuthenticatedDynamicInstanceKey(e,t,n){if(e!==void 0&&t===void 0)throw Error(`${n} Authenticated dynamic connections must set "instanceKey" to a stable, non-secret account or tenant identifier.`)}function omitUndefined(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0))}export{resolveConnectionDefinition,resolveDynamicConnectionValue};
|
|
1
|
+
import{expectObjectRecord}from"#internal/authored-module.js";import{toErrorMessage}from"#shared/errors.js";import{normalizeMcpClientConnectionDefinition,normalizeOpenApiConnectionDefinition}from"#internal/authored-definition/connection.js";import{readStampedConnectionProtocol}from"#public/definitions/connections/protocol.js";import{connectionDefinitionKey,registerDefinitionSource}from"#internal/authored-definition/source-identity.js";import{normalizeAuthorizationSpec}from"#shared/validate-authorization.js";import{ResolveAgentError,loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{createConnectionInstanceId}from"#runtime/connections/instance-identity.js";async function resolveConnectionDefinition(e,t,n){try{let r=await loadResolvedModuleExport({definition:e,kindLabel:`connection`,moduleMap:t,nodeId:n}),i=expectObjectRecord(r,`Expected the connection export "${e.exportName??`default`}" from "${e.logicalPath}" to return an object.`);registerDefinitionSource(i,{kind:`connection`,logicalPath:e.logicalPath,name:e.connectionName},connectionDefinitionKey(e.url,e.description));let a=i.auth!==void 0,o=i.headers!==void 0,s=e.protocol===`openapi`?i.operations:i.tools,c={connectionName:e.connectionName,description:e.description,exportName:e.exportName,logicalPath:e.logicalPath,instanceId:createConnectionInstanceId({connectionName:e.connectionName,instanceKey:typeof i.instanceKey==`string`?i.instanceKey:void 0,protocol:e.protocol,sourceId:e.sourceId,url:e.url}),protocol:e.protocol,sourceId:e.sourceId,sourceKind:`module`,url:e.url};if(a){if(typeof i.auth==`function`)c.authorization=i.auth;else try{c.authorization=normalizeAuthorizationSpec(i.auth,`Connection "${e.connectionName}" at "${e.logicalPath}":`)}catch(t){throw new ResolveAgentError(toErrorMessage(t),{logicalPath:e.logicalPath,sourceId:e.sourceId})}}if(e.protocol===`mcp`&&i.protocolVersionDiscovery!==void 0){if(typeof i.protocolVersionDiscovery!=`boolean`)throw Error(`"protocolVersionDiscovery" must be a boolean.`);c.protocolVersionDiscovery=i.protocolVersionDiscovery}if(e.protocol===`mcp`&&i.forwardPrincipal!==void 0){if(typeof i.forwardPrincipal!=`boolean`)throw Error(`"forwardPrincipal" must be a boolean.`);c.forwardPrincipal=i.forwardPrincipal}if(e.experimental_events===!0){let t=normalizeMcpClientConnectionDefinition(i,`Connection "${e.connectionName}":`).experimental_events,n=typeof c.authorization==`object`?c.authorization:void 0;if(t===void 0||n?.vercelConnect?.experimental_events===void 0)throw new ResolveAgentError(`Connection "${e.connectionName}": experimental_events requires a static Connect auth provider with the events bridge.`,{logicalPath:e.logicalPath,sourceId:e.sourceId});c.experimental_events={callbacks:t,authorization:n,connector:n.vercelConnect.connector,backend:n.vercelConnect.experimental_events}}return o&&(c.headers=i.headers),i.toolCall!==void 0&&(c.toolCall=i.toolCall),s!==void 0&&(c.tools=s),e.protocol===`openapi`&&i.spec!==void 0&&(c.spec=i.spec),typeof i.approval==`function`&&(c.approval=i.approval),c}catch(t){throw t instanceof ResolveAgentError?t:new ResolveAgentError(`Failed to resolve connection "${e.connectionName}" from "${e.logicalPath}": ${toErrorMessage(t)}`,{logicalPath:e.logicalPath,sourceId:e.sourceId})}}function resolveDynamicConnectionValue(e,t){let n=readStampedConnectionProtocol(e),r=`Dynamic connection "${t.connectionName}" from "${t.logicalPath}" must be created by defineMcpClientConnection() or defineOpenAPIConnection().`;if(n===void 0)throw Error(r);if(registerDefinitionSource(e,{kind:`connection`,logicalPath:t.logicalPath,name:t.connectionName}),n===`openapi`){let i=normalizeOpenApiConnectionDefinition(e,r);return assertAuthenticatedDynamicInstanceKey(i.auth,i.instanceKey,r),omitUndefined({approval:i.approval,authorization:i.auth,connectionName:t.connectionName,description:i.description,exportName:t.exportName,headers:i.headers,instanceId:createConnectionInstanceId({connectionName:t.connectionName,instanceKey:i.instanceKey,protocol:n,sourceId:t.sourceId,url:i.baseUrl??``}),logicalPath:t.logicalPath,protocol:n,sourceId:t.sourceId,sourceKind:`module`,spec:i.spec,toolCall:i.toolCall,tools:i.operations,url:i.baseUrl??``})}let i=normalizeMcpClientConnectionDefinition(e,r);if(i.experimental_events!==void 0)throw Error(`${r} experimental_events requires a statically authored connection so eve can mount its receiver at build time.`);return assertAuthenticatedDynamicInstanceKey(i.auth,i.instanceKey,r),omitUndefined({approval:i.approval,authorization:i.auth,connectionName:t.connectionName,description:i.description,exportName:t.exportName,headers:i.headers,instanceId:createConnectionInstanceId({connectionName:t.connectionName,instanceKey:i.instanceKey,protocol:n,sourceId:t.sourceId,url:i.url}),logicalPath:t.logicalPath,protocol:n,sourceId:t.sourceId,sourceKind:`module`,toolCall:i.toolCall,protocolVersionDiscovery:i.protocolVersionDiscovery,forwardPrincipal:i.forwardPrincipal,tools:i.tools,url:i.url})}function assertAuthenticatedDynamicInstanceKey(e,t,n){if(e!==void 0&&t===void 0)throw Error(`${n} Authenticated dynamic connections must set "instanceKey" to a stable, non-secret account or tenant identifier.`)}function omitUndefined(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0))}export{resolveConnectionDefinition,resolveDynamicConnectionValue};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { StandardSchemaV1 } from "#compiled/@standard-schema/spec/index.js";
|
|
2
|
-
import type { SessionSchedule } from "#context/session-schedule.js";
|
|
3
2
|
import type { ScheduleClient, ScheduleClientCreate, ScheduleClientUpdate, DynamicSchedulesDefinition, ScheduleEnvelope, ScheduleScopeContext } from "#public/schedules/subscription.js";
|
|
4
3
|
export interface ScheduleBoundCallContext extends ScheduleScopeContext {
|
|
5
4
|
readonly application: string;
|
|
@@ -26,4 +25,3 @@ export interface ScheduleCollectionClient<TInput, TPrepared> extends ScheduleCli
|
|
|
26
25
|
update(name: string, patch: ScheduleClientUpdate<TInput>, approved?: PreparedScheduleUpdate): Promise<import("#public/schedules/subscription.js").ScheduleRecord>;
|
|
27
26
|
}
|
|
28
27
|
export declare function createScheduleCollectionClient<TPayload, TPrepared = TPayload>(definition: DynamicSchedulesDefinition<TPayload, StandardSchemaV1<unknown, TPayload>, TPrepared>, callContext: ScheduleBoundCallContext): ScheduleCollectionClient<TPayload, TPrepared>;
|
|
29
|
-
export declare function assertScheduleManagementAllowed(schedule?: SessionSchedule): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHash,randomUUID}from"node:crypto";import{
|
|
1
|
+
import{createHash,randomUUID}from"node:crypto";import{loadContext}from"#context/container.js";import{projectScheduleRecord}from"#runtime/schedules/record.js";import{createScheduleCollectionPayload,validateSchedulePayload}from"#runtime/schedules/payload.js";import{isDeepStrictEqual}from"node:util";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{resolveScheduleTiming,validateScheduleListLimit,validateScheduleName}from"#runtime/schedules/validation.js";import{dispatchScheduledOccurrence}from"#runtime/schedules/dispatch-occurrence.js";import{byPrincipal}from"#public/schedules/scope.js";function createScheduleCollectionClient(e,t){let n=t.operationId??randomUUID,contextFor=(e,n)=>{let r={...t,operation:e};return n!==void 0&&(r.name=n),r},resolveNamespace=async(r,i)=>{let a=contextFor(r,i),o=e.scope===void 0?byPrincipal(a):await e.scope({...a,operation:r});if(o===null)throw Error(`Schedule ${r} is not available in this context.`);return validateScope(o),{scope:o,provider:{abortSignal:t.abortSignal,collection:t.collection,namespace:deriveScheduleNamespace(t.application,t.collection,o),operationId:n(),target:{key:t.application,deliver:async({payload:n,occurrence:r})=>{await dispatchScheduledOccurrence({bundle:loadContext().require(BundleKey),collection:t.collection,definition:e,occurrence:{...r,collection:t.collection},payload:n})}}}}},prepareEnvelope=async(n,r,i,a)=>{let o=principalReference(t.session.auth.current);if(o===null)throw Error(`Writing a schedule payload requires an authenticated principal.`);let s=await validateSchedulePayload(e.inputSchema,n),c=e.preparePayload===void 0?s:await e.preparePayload(s,{...contextFor(i,a),operation:i,name:a});return createScheduleCollectionPayload({application:t.application,collection:t.collection,envelope:{version:3,payload:c,scope:r,principal:o}}).envelope},prepareUpdate=async(t,n)=>{let r=Object.keys(n).filter(e=>e!==`expression`&&e!==`payload`);if(r.length>0)throw Error(`Schedule update does not support: ${r.join(`, `)}.`);if(n.expression===void 0&&n.payload===void 0)throw Error(`Schedule update requires an expression or replacement payload.`);let i=validateScheduleName(t);n.expression!==void 0&&resolveScheduleTiming(n.expression);let{scope:a,provider:o}=await resolveNamespace(`update`,i);if(await e.provider.get(o,i)===null)throw Error(`Schedule was not found in the authorized scope.`);return{prepared:snapshotPreparedWrite({name:i,namespace:o.namespace,expression:n.expression,envelope:n.payload===void 0?void 0:await prepareEnvelope(n.payload,a,`update`,i)}),provider:o}},prepareCreation=async e=>{let t=validateScheduleName(e.name);resolveScheduleTiming(e.expression);let{scope:n,provider:r}=await resolveNamespace(`create`,t);return{prepared:snapshotPreparedWrite({displayName:t,expression:e.expression,envelope:await prepareEnvelope(e.payload,n,`create`,t)}),provider:r}};return{async prepareCreate(e){return(await prepareCreation(e)).prepared},async create(n,r){let{prepared:i,provider:a}=await prepareCreation(n);if(r!==void 0&&!isDeepStrictEqual(i,r))throw Error(`Schedule creation changed after approval. Request a new creation approval; no schedule was written.`);let o=`${i.displayName.slice(0,218)}--${randomUUID()}`,s=resolveScheduleTiming(n.expression),c=createScheduleCollectionPayload({application:t.application,collection:t.collection,envelope:i.envelope});return projectScheduleRecord(await e.provider.create(a,{expression:s,name:o,payload:c}))},async prepareUpdate(e,t){return(await prepareUpdate(e,t)).prepared},async update(n,r,i){let{prepared:a,provider:o}=await prepareUpdate(n,r);if(i!==void 0&&!isDeepStrictEqual(a,i))throw Error(`Schedule update changed after approval. Request a new update approval; no schedule was written.`);let s={expression:a.expression===void 0?void 0:resolveScheduleTiming(a.expression),payload:a.envelope===void 0?void 0:createScheduleCollectionPayload({application:t.application,collection:t.collection,envelope:a.envelope})};return projectScheduleRecord(await e.provider.update(o,a.name,s))},async delete(t){let n=validateScheduleName(t),{provider:r}=await resolveNamespace(`delete`,n);return await e.provider.delete(r,n)},async disable(t){let n=validateScheduleName(t),{provider:r}=await resolveNamespace(`disable`,n);return projectScheduleRecord(await e.provider.disable(r,n))},async enable(t){let n=validateScheduleName(t),{provider:r}=await resolveNamespace(`enable`,n);return projectScheduleRecord(await e.provider.enable(r,n))},async get(t){let n=validateScheduleName(t),{provider:r}=await resolveNamespace(`get`,n),i=await e.provider.get(r,n);return i===null?null:projectScheduleRecord(i)},async invoke(t){let n=validateScheduleName(t),{provider:r}=await resolveNamespace(`invoke`,n);await e.provider.invoke(r,n)},async list(t={}){let n=validateScheduleListLimit(t.limit),{provider:r}=await resolveNamespace(`list`),i={};t.cursor?.trim()&&(i.cursor=t.cursor.trim()),n!==void 0&&(i.limit=n);let a=await e.provider.list(r,i);return{...a,data:a.data.map(projectScheduleRecord)}}}}function snapshotPreparedWrite(e){let t=JSON.stringify(e);if(Buffer.byteLength(t)>65536)throw Error(`Prepared schedule write exceeds the 64 KB limit, including timing and payload.`);return JSON.parse(t)}function principalReference(e){if(e===null||e.principalType===`anonymous`||e.principalType===`runtime`)return null;let t={type:e.principalType,authenticator:e.authenticator,principalId:e.principalId};return e.issuer!==void 0&&(t.issuer=e.issuer),e.subject!==void 0&&(t.subject=e.subject),t}function validateScope(e){let t=typeof e==`string`?[e]:e;if(t.length===0||t.some(e=>typeof e!=`string`||e.trim().length===0))throw Error(`Schedule scope must be a non-empty string or tuple of non-empty strings.`)}function deriveScheduleNamespace(e,t,n){if(e.trim().length===0)throw Error(`Schedule application must not be empty.`);return`eve-${createHash(`sha256`).update(JSON.stringify([`eve-schedule-namespace-v2`,e,t,n])).digest(`base64url`)}`}export{createScheduleCollectionClient};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { Experimental_ConnectionEvents } from "#public/definitions/connections/events.js";
|
|
2
|
+
import type { ConnectionEventsBackend } from "#shared/connection-events.js";
|
|
1
3
|
import type { ChannelAdapter } from "#channel/adapter.js";
|
|
2
4
|
import type { CompiledChannel } from "#channel/compiled-channel.js";
|
|
3
5
|
import type { NormalizedChannelCorsOptions } from "#channel/cors.js";
|
|
@@ -76,7 +78,16 @@ export type ResolvedScheduleDefinition = Readonly<SourceRef & {
|
|
|
76
78
|
* Both `authorization` and `headers` are optional — a connection to a
|
|
77
79
|
* server that requires no authentication (e.g. localhost) may omit both.
|
|
78
80
|
*/
|
|
81
|
+
/** A connection's event watching, checked once when the connection resolves. */
|
|
82
|
+
export interface ResolvedConnectionEvents {
|
|
83
|
+
readonly callbacks: Experimental_ConnectionEvents;
|
|
84
|
+
/** The static Connect authorization every watch subscribes and runs under. */
|
|
85
|
+
readonly authorization: Readonly<AuthorizationDefinition>;
|
|
86
|
+
readonly connector: string;
|
|
87
|
+
readonly backend: ConnectionEventsBackend;
|
|
88
|
+
}
|
|
79
89
|
export interface ResolvedConnectionDefinition extends ResolvedModuleSourceRef {
|
|
90
|
+
readonly experimental_events?: ResolvedConnectionEvents;
|
|
80
91
|
readonly protocolVersionDiscovery?: boolean;
|
|
81
92
|
/** MCP only: send the turn's principals in `eve-forwarded-principal`. */
|
|
82
93
|
readonly forwardPrincipal?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"../update/package-json.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{agentTemplateFiles,formatEveDependencySpecifier,resolveEvePackageContract}from"./project.js";import{readFile}from"node:fs/promises";import{join}from"node:path";const DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`optionalDependencies`,`peerDependencies`];function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function hasDeclaredDependency(e,t){if(!isJsonObject(e))return!1;for(let n of DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function addAgentToProject(e){let t=e.packageManager??`pnpm`,n=join(e.projectRoot,`package.json`);if(!await pathExists(n))throw Error(`Cannot add an eve agent to "${e.projectRoot}" because it has no package.json. Run \`eve init <name>\` to create a new project instead.`);let r;try{r=JSON.parse(await readFile(n,`utf8`))}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`Cannot add an eve agent because "${n}" is not valid JSON. No files were changed. Fix the file, then retry eve init. ${t}`)}let i=agentTemplateFiles(e.model,e.reasoning),a=[];for(let t of Object.keys(i))await pathExists(join(e.projectRoot,t))&&a.push(t);if(a.length===0&&await pathExists(join(e.projectRoot,`agent`))&&a.push(`agent/`),a.length>0)throw Error(`Cannot add an eve agent to "${e.projectRoot}" because it already has: ${a.join(`, `)}.`);let o=resolveEvePackageContract(e.evePackage),s=resolveVersionToken(`aiPackageVersion`,e.aiPackageVersion??`^7.0.137`),c=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.2
|
|
1
|
+
import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"../update/package-json.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{agentTemplateFiles,formatEveDependencySpecifier,resolveEvePackageContract}from"./project.js";import{readFile}from"node:fs/promises";import{join}from"node:path";const DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`optionalDependencies`,`peerDependencies`];function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function hasDeclaredDependency(e,t){if(!isJsonObject(e))return!1;for(let n of DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function addAgentToProject(e){let t=e.packageManager??`pnpm`,n=join(e.projectRoot,`package.json`);if(!await pathExists(n))throw Error(`Cannot add an eve agent to "${e.projectRoot}" because it has no package.json. Run \`eve init <name>\` to create a new project instead.`);let r;try{r=JSON.parse(await readFile(n,`utf8`))}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`Cannot add an eve agent because "${n}" is not valid JSON. No files were changed. Fix the file, then retry eve init. ${t}`)}let i=agentTemplateFiles(e.model,e.reasoning),a=[];for(let t of Object.keys(i))await pathExists(join(e.projectRoot,t))&&a.push(t);if(a.length===0&&await pathExists(join(e.projectRoot,`agent`))&&a.push(`agent/`),a.length>0)throw Error(`Cannot add an eve agent to "${e.projectRoot}" because it already has: ${a.join(`, `)}.`);let o=resolveEvePackageContract(e.evePackage),s=resolveVersionToken(`aiPackageVersion`,e.aiPackageVersion??`^7.0.137`),c=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.5.2`),l=resolveVersionToken(`zodPackageVersion`,e.zodPackageVersion??`4.5.4`),u=[];for(let[t,n]of Object.entries(i)){let r=join(e.projectRoot,t);await writeTextFile(r,n),u.push(r)}let d={"@vercel/connect":c,ai:s,eve:formatEveDependencySpecifier(o.version),zod:l},f={};for(let[e,t]of Object.entries(d))hasDeclaredDependency(r,e)||(f[e]=t);let p={};Object.keys(f).length>0&&(p.dependencies=f),isPackageManagerWorkspaceMember(t,e.projectRoot)||(p.nodeEngineRequirement=o.nodeEngine);let m=await patchPackageJson(n,p),h=await patchWorkspaceRootPackageJson(t,e.projectRoot,{nodeEngineRequirement:o.nodeEngine}),g=h.nodeEngineOverride??m.nodeEngineOverride,_=await applyPackageManagerWorkspaceConfiguration({packageManager:t,projectRoot:e.projectRoot});return{filesWritten:u,dependenciesAdded:Object.keys(f).sort(),nodeEngineOverride:g,configurationFilesChanged:[...m.changed?[n]:[],...h.changed&&h.path!==void 0?[h.path]:[],..._.filesWritten]}}export{addAgentToProject};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{pinnedNodeEngineMajor}from"../../node-engine.js";import{parseChatGptModelSelection}from"../../../shared/chatgpt-model.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{DEFAULT_CONNECT_PACKAGE_VERSION,resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_CHANNEL_TEMPLATES}from"./web-template.js";import{AGENT_INSTRUCTIONS_TEMPLATE}from"./instructions-template.js";import{SCAFFOLDED_AGENT_PATHS}from"./agent-paths.js";import{mkdir,readdir,stat}from"node:fs/promises";import{basename,join,resolve}from"node:path";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.137`,DEFAULT_ZOD_PACKAGE_VERSION=`4.5.4`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.
|
|
1
|
+
import{pinnedNodeEngineMajor}from"../../node-engine.js";import{parseChatGptModelSelection}from"../../../shared/chatgpt-model.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{DEFAULT_CONNECT_PACKAGE_VERSION,resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_CHANNEL_TEMPLATES}from"./web-template.js";import{AGENT_INSTRUCTIONS_TEMPLATE}from"./instructions-template.js";import{SCAFFOLDED_AGENT_PATHS}from"./agent-paths.js";import{mkdir,readdir,stat}from"node:fs/promises";import{basename,join,resolve}from"node:path";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.137`,DEFAULT_ZOD_PACKAGE_VERSION=`4.5.4`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.80.1`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e,t){return{[SCAFFOLDED_AGENT_PATHS.config]:renderAgentTemplate(e,t),[SCAFFOLDED_AGENT_PATHS.channel]:WEB_CHANNEL_TEMPLATES.default,[SCAFFOLDED_AGENT_PATHS.instructions]:AGENT_INSTRUCTIONS_TEMPLATE}}function renderAgentTemplate(e,t){let n=parseChatGptModelSelection(e);return n===void 0?BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(t)):`import { defineAgent } from "eve";\nimport { chatgpt } from "eve/models/openai";\n\nexport default defineAgent({\n model: chatgpt(${JSON.stringify(n)}),\n${reasoningTemplateLine(t)}});\n`}function reasoningTemplateLine(e){return e===void 0||e===`provider-default`?``:` reasoning: "${e}",\n`}function renderTemplate(e,t){return e===BASE_AGENT_TEMPLATE&&parseChatGptModelSelection(t.model)!==void 0?renderAgentTemplate(t.model,t.reasoning):e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(t.reasoning)).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
|
|
2
2
|
|
|
3
3
|
export default defineAgent({
|
|
4
4
|
model: "__EVE_INIT_MODEL__",
|
|
@@ -114,4 +114,4 @@ __EVE_INIT_REASONING__ modelOptions: {
|
|
|
114
114
|
},
|
|
115
115
|
},
|
|
116
116
|
});
|
|
117
|
-
`:BASE_AGENT_TEMPLATE,...SHARED_TEMPLATE_FILES,"package.json":packageJsonTemplate(e.includeRootOnlyPackageJsonFields)}}async function assertCanCreateInPlace(e,t){if(!await pathExists(e))return;let n=await readdir(e),r=blockingCreateInPlaceEntries(n);if(r.length>0&&!t){let e=r.slice(0,5).join(`, `),t=r.length>5?`, and ${r.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${e}${t}. Use an empty directory.`)}}async function scaffoldBaseProject(e){let t=resolve(e.targetDirectory??process.cwd(),e.projectName),n=e.projectName===`.`,r=e.overwriteExisting??!1,i=e.byokProvider??!1,a=e.packageManager??`pnpm`,o=resolveEvePackageContract(e.evePackage),s=pinnedNodeEngineMajor(o.nodeEngine),c=resolve(e.workspaceProbeDirectory??t),l=isPackageManagerWorkspaceMember(a,c);if(n)await assertCanCreateInPlace(t,r);else if(await pathExists(t))throw Error(`Cannot create project because "${t}" already exists.`);let u={appName:basename(t),model:e.model,reasoning:e.reasoning,eveVersion:o.version,aiPackageVersion:resolveVersionToken(`aiPackageVersion`,e.aiPackageVersion??`^7.0.137`),connectPackageVersion:resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.2
|
|
117
|
+
`:BASE_AGENT_TEMPLATE,...SHARED_TEMPLATE_FILES,"package.json":packageJsonTemplate(e.includeRootOnlyPackageJsonFields)}}async function assertCanCreateInPlace(e,t){if(!await pathExists(e))return;let n=await readdir(e),r=blockingCreateInPlaceEntries(n);if(r.length>0&&!t){let e=r.slice(0,5).join(`, `),t=r.length>5?`, and ${r.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${e}${t}. Use an empty directory.`)}}async function scaffoldBaseProject(e){let t=resolve(e.targetDirectory??process.cwd(),e.projectName),n=e.projectName===`.`,r=e.overwriteExisting??!1,i=e.byokProvider??!1,a=e.packageManager??`pnpm`,o=resolveEvePackageContract(e.evePackage),s=pinnedNodeEngineMajor(o.nodeEngine),c=resolve(e.workspaceProbeDirectory??t),l=isPackageManagerWorkspaceMember(a,c);if(n)await assertCanCreateInPlace(t,r);else if(await pathExists(t))throw Error(`Cannot create project because "${t}" already exists.`);let u={appName:basename(t),model:e.model,reasoning:e.reasoning,eveVersion:o.version,aiPackageVersion:resolveVersionToken(`aiPackageVersion`,e.aiPackageVersion??`^7.0.137`),connectPackageVersion:resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.5.2`),zodPackageVersion:resolveVersionToken(`zodPackageVersion`,e.zodPackageVersion??`4.5.4`),typescriptPackageVersion:resolveVersionToken(`typescriptPackageVersion`,e.typescriptPackageVersion??`7.0.2`),nodeTypesVersion:s,nodeEngine:s};await mkdir(t,{recursive:!0});for(let[a,o]of Object.entries(templateFiles({byokProvider:i,includeRootOnlyPackageJsonFields:!l}))){let i=`${t}/${a}`,s=await pathExists(i);await writeTextFile(i,renderTemplate(o,u),{force:n&&r}),s&&await e.onOverwriteFile?.(i)}return await applyPackageManagerWorkspaceConfiguration({packageManager:a,projectRoot:t,workspaceProbeRoot:c,onWorkspaceRootMutation:e.onWorkspaceRootMutation}),await patchWorkspaceRootPackageJson(a,c,{nodeEngineRequirement:o.nodeEngine,onWorkspaceRootMutation:e.onWorkspaceRootMutation}),t}async function isEveProject(e){for(let t of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)try{return await stat(join(e,`agent`,`agent${t}`)),!0}catch{}return!1}export{CURRENT_DIRECTORY_PROJECT_NAME,DEFAULT_AI_PACKAGE_VERSION,DEFAULT_CONNECT_PACKAGE_VERSION,DEFAULT_EVE_PACKAGE_CONTRACT,DEFAULT_ZOD_PACKAGE_VERSION,ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX,agentTemplateFiles,byokProviderEnvVar,formatEveDependencySpecifier,isEveProject,modelProviderSlug,resolveEvePackageContract,scaffoldBaseProject};
|
|
@@ -4,7 +4,7 @@ import { slackChannel } from "eve/channels/slack";
|
|
|
4
4
|
export default slackChannel({
|
|
5
5
|
credentials: connectSlackCredentials(${JSON.stringify(e)}),
|
|
6
6
|
});
|
|
7
|
-
`}const SLACK_ENV_EXAMPLE_VALUES={SLACK_BOT_TOKEN:``,SLACK_SIGNING_SECRET:``};function renderWebAppTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t).replaceAll(`__EVE_INIT_WITH_EVE_OPTIONS__`,``)}async function ensureWebVercelJson(e){return await pathExists(e)?`skipped`:(await writeTextFile(e,`${JSON.stringify({$schema:`https://openapi.vercel.sh/vercel.json`},null,2)}\n`,{force:!0}),`written`)}async function findCompetingNextConfigFiles(e){let t=[];for(let n of WEB_COMPETING_NEXT_CONFIG_PATHS){let r=join(e,n);await pathExists(r)&&t.push(r)}return t}async function ensureChannel(e){switch(e.kind){case`slack`:return ensureSlackChannel({...e,kind:`slack`});case`web`:return ensureWebChannel({...e,kind:`web`})}}async function ensureWebChannel(e){let t=join(e.projectRoot,`package.json`),n=join(e.projectRoot,`app/page.tsx`),r=await pathExists(n);if(!e.force&&!e.skipDependencyMutation&&await isNextJsProject(e.projectRoot))return{kind:`web`,action:`skipped`,skipReason:`nextjs-project`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let i=resolveWebPackageVersions(e.webPackageVersions,e.webAuthentication),a=e.packageManager??`pnpm`,o=resolve(e.workspaceProbeDirectory??e.projectRoot),s=await patchWebPackageJson(e.projectRoot,a,o,i,e.onWorkspaceRootMutation,!e.skipDependencyMutation,e.webAuthentication),c=[],l=[],u=[],d=[],f=basename(resolve(e.projectRoot));if(e.configureVercelServices??!0){let t=join(e.projectRoot,`vercel.json`);await ensureWebVercelJson(t)===`written`?c.push(t):d.push(t)}let p=await applyPackageManagerWorkspaceConfiguration({packageManager:a,projectRoot:e.projectRoot,workspaceProbeRoot:o,onWorkspaceRootMutation:e.onWorkspaceRootMutation});if(c.push(...p.filesWritten),d.push(...p.filesSkipped),!e.skipDependencyMutation){let t=WEB_CHANNEL_TEMPLATES[e.webAuthentication??`default`],n={...WEB_APP_TEMPLATE_FILES,...e.webAuthentication===`sign-in-with-vercel`?WEB_APP_SIGN_IN_WITH_VERCEL_TEMPLATE_FILES:{},[WEB_CHANNEL_PATH]:t};for(let[t,r]of Object.entries(n)){let n=join(e.projectRoot,t);if(t===WEB_CHANNEL_PATH&&!e.force&&await pathExists(n)){d.push(n);continue}let i=await pathExists(n);await writeTextFile(n,renderWebAppTemplate(r,f),{force:!0}),c.push(n),i&&l.push(n)}}u.push(...await findCompetingNextConfigFiles(e.projectRoot));let m=[...new Set(c)],h=[...new Set(d)].filter(e=>!m.includes(e)),g={kind:`web`,action:r?`overwritten`:`created`,filesWritten:m,filesSkipped:h,packageJsonUpdated:s.mutations};return l.length>0&&(g.filesOverwritten=l),u.length>0&&(g.competingNextConfigFiles=u),s.nodeEngineOverride!==void 0&&(g.nodeEngineOverride=s.nodeEngineOverride),g}async function ensureSlackChannel(e){let t=join(e.projectRoot,`agent/channels/slack.ts`),n=await pathExists(t);if(!e.force&&n)return{kind:`slack`,action:`skipped`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let r=e.slackCredentials??`vercel-connect`,i=e.slackConnectorSlug??await deriveSlackConnectorSlug(e.projectRoot),a,o=[],s=[t],c=[],l;if(r===`vercel-connect`){if(!e.skipDependencyMutation){let t=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.2
|
|
7
|
+
`}const SLACK_ENV_EXAMPLE_VALUES={SLACK_BOT_TOKEN:``,SLACK_SIGNING_SECRET:``};function renderWebAppTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t).replaceAll(`__EVE_INIT_WITH_EVE_OPTIONS__`,``)}async function ensureWebVercelJson(e){return await pathExists(e)?`skipped`:(await writeTextFile(e,`${JSON.stringify({$schema:`https://openapi.vercel.sh/vercel.json`},null,2)}\n`,{force:!0}),`written`)}async function findCompetingNextConfigFiles(e){let t=[];for(let n of WEB_COMPETING_NEXT_CONFIG_PATHS){let r=join(e,n);await pathExists(r)&&t.push(r)}return t}async function ensureChannel(e){switch(e.kind){case`slack`:return ensureSlackChannel({...e,kind:`slack`});case`web`:return ensureWebChannel({...e,kind:`web`})}}async function ensureWebChannel(e){let t=join(e.projectRoot,`package.json`),n=join(e.projectRoot,`app/page.tsx`),r=await pathExists(n);if(!e.force&&!e.skipDependencyMutation&&await isNextJsProject(e.projectRoot))return{kind:`web`,action:`skipped`,skipReason:`nextjs-project`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let i=resolveWebPackageVersions(e.webPackageVersions,e.webAuthentication),a=e.packageManager??`pnpm`,o=resolve(e.workspaceProbeDirectory??e.projectRoot),s=await patchWebPackageJson(e.projectRoot,a,o,i,e.onWorkspaceRootMutation,!e.skipDependencyMutation,e.webAuthentication),c=[],l=[],u=[],d=[],f=basename(resolve(e.projectRoot));if(e.configureVercelServices??!0){let t=join(e.projectRoot,`vercel.json`);await ensureWebVercelJson(t)===`written`?c.push(t):d.push(t)}let p=await applyPackageManagerWorkspaceConfiguration({packageManager:a,projectRoot:e.projectRoot,workspaceProbeRoot:o,onWorkspaceRootMutation:e.onWorkspaceRootMutation});if(c.push(...p.filesWritten),d.push(...p.filesSkipped),!e.skipDependencyMutation){let t=WEB_CHANNEL_TEMPLATES[e.webAuthentication??`default`],n={...WEB_APP_TEMPLATE_FILES,...e.webAuthentication===`sign-in-with-vercel`?WEB_APP_SIGN_IN_WITH_VERCEL_TEMPLATE_FILES:{},[WEB_CHANNEL_PATH]:t};for(let[t,r]of Object.entries(n)){let n=join(e.projectRoot,t);if(t===WEB_CHANNEL_PATH&&!e.force&&await pathExists(n)){d.push(n);continue}let i=await pathExists(n);await writeTextFile(n,renderWebAppTemplate(r,f),{force:!0}),c.push(n),i&&l.push(n)}}u.push(...await findCompetingNextConfigFiles(e.projectRoot));let m=[...new Set(c)],h=[...new Set(d)].filter(e=>!m.includes(e)),g={kind:`web`,action:r?`overwritten`:`created`,filesWritten:m,filesSkipped:h,packageJsonUpdated:s.mutations};return l.length>0&&(g.filesOverwritten=l),u.length>0&&(g.competingNextConfigFiles=u),s.nodeEngineOverride!==void 0&&(g.nodeEngineOverride=s.nodeEngineOverride),g}async function ensureSlackChannel(e){let t=join(e.projectRoot,`agent/channels/slack.ts`),n=await pathExists(t);if(!e.force&&n)return{kind:`slack`,action:`skipped`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let r=e.slackCredentials??`vercel-connect`,i=e.slackConnectorSlug??await deriveSlackConnectorSlug(e.projectRoot),a,o=[],s=[t],c=[],l;if(r===`vercel-connect`){if(!e.skipDependencyMutation){let t=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.5.2`);o=await ensurePackageDependency(join(e.projectRoot,`package.json`),`@vercel/connect`,t)}a=buildSlackConnectTemplate(e.slackConnectorUid??`slack/${i}`)}else{a=`import { slackChannel } from "eve/channels/slack";
|
|
8
8
|
|
|
9
9
|
export default slackChannel();
|
|
10
10
|
`;let t=join(e.environmentRoot??e.projectRoot,`.env.example`);l={path:t,...await pathExists(t)?{content:await readFile(t,`utf8`)}:{}},(await appendEnv(t,SLACK_ENV_EXAMPLE_VALUES)).written.length>0?s.push(t):c.push(t)}try{await writeTextFile(t,a,{force:e.force})}catch(e){throw l!==void 0&&(l.content===void 0?await unlink(l.path):await writeFile(l.path,l.content,`utf8`)),e}let u={kind:`slack`,action:n?`overwritten`:`created`,filesWritten:s,filesSkipped:c,packageJsonUpdated:o,slackConnectorSlug:i};return n&&(u.filesOverwritten=[t]),u}async function listAuthoredChannels(e){let t=join(e,`channels`),n;try{n=await readdir(t,{withFileTypes:!0})}catch(e){if(e.code===`ENOENT`)return[];throw e}let r=[];for(let e of n){if(e.isFile()){let t=getSupportedModuleBaseName(e.name);t!==null&&r.push(t);continue}if(e.isDirectory())try{(await readdir(join(t,e.name))).some(e=>matchesSupportedModuleBaseName(e,`connection`))&&r.push(e.name)}catch{}}return r.sort()}export{DEFAULT_SLACK_CONNECTOR_SLUG,SLACK_CHANNEL_DEFAULT_ROUTE,deriveSlackConnectorSlug,ensureChannel,hasVercelHostFramework,isNextJsProject,listAuthoredChannels,normalizeSlackConnectorSlug,resolveVercelHostFrameworkPreset};
|
|
@@ -15,7 +15,7 @@ export default defineOpenAPIConnection({
|
|
|
15
15
|
spec: "${e.spec}",
|
|
16
16
|
${i} description: "${t}",
|
|
17
17
|
${authBlock(n)}});
|
|
18
|
-
`}function renderTemplate(e,t,n,r){return e===`mcp`?renderMcpTemplate(t,n,r):renderOpenApiTemplate(t,n,r)}function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function ensureConnectDependency(e,t){if(!await pathExists(e))return[];let n=JSON.parse(await readFile(e,`utf8`));return(isJsonObject(n)&&isJsonObject(n.dependencies)?n.dependencies[CONNECT_PACKAGE_NAME]:void 0)===t?[]:(await patchPackageJson(e,{dependencies:{[CONNECT_PACKAGE_NAME]:t}}),[{path:e,dependencies:[CONNECT_PACKAGE_NAME],devDependencies:[],scripts:[]}])}async function ensureConnectionDependencies(e){let t=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.2
|
|
18
|
+
`}function renderTemplate(e,t,n,r){return e===`mcp`?renderMcpTemplate(t,n,r):renderOpenApiTemplate(t,n,r)}function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function ensureConnectDependency(e,t){if(!await pathExists(e))return[];let n=JSON.parse(await readFile(e,`utf8`));return(isJsonObject(n)&&isJsonObject(n.dependencies)?n.dependencies[CONNECT_PACKAGE_NAME]:void 0)===t?[]:(await patchPackageJson(e,{dependencies:{[CONNECT_PACKAGE_NAME]:t}}),[{path:e,dependencies:[CONNECT_PACKAGE_NAME],devDependencies:[],scripts:[]}])}async function ensureConnectionDependencies(e){let t=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.5.2`);return ensureConnectDependency(join(e.projectRoot,`package.json`),t)}function envKeyPresent(e,t){return RegExp(`^\\s*(?:export\\s+)?${t}\\s*=`,`m`).test(e)}async function seedEnvPlaceholders(e,t){if(t.length===0)return[];let n=``;await pathExists(e)&&(n=await readFile(e,`utf8`));let r=t.filter(e=>!envKeyPresent(n,e));if(r.length===0)return[];let i=`${n.length>0&&!n.endsWith(`
|
|
19
19
|
`)?`
|
|
20
20
|
`:``}${r.map(e=>`${e}=`).join(`
|
|
21
|
-
`)}\n`;return await writeFile(e,n+i,`utf8`),r}async function ensureConnection(e){let t=e.slug??e.entry.slug,n=resolveAuth(e.entry),r=endpointForProtocol(e.entry,e.protocol);if(r===null)throw Error(`Connection "${t}" is missing a ${e.protocol===`mcp`?`mcp.url`:`openapi.spec`} endpoint for protocol "${e.protocol}".`);let i=join(e.projectRoot,USER_AUTHORED_CONNECTION_DIR,`${t}.ts`),a=envKeysForAuth(n),o=await pathExists(i);if(!e.force&&o)return{slug:t,protocol:e.protocol,action:`skipped`,filePath:i,filesWritten:[],filesSkipped:[i],packageJsonUpdated:[],envKeysAdded:[],envKeysRequired:a};let s=[];if(n.kind===`connect`){let t=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.2
|
|
21
|
+
`)}\n`;return await writeFile(e,n+i,`utf8`),r}async function ensureConnection(e){let t=e.slug??e.entry.slug,n=resolveAuth(e.entry),r=endpointForProtocol(e.entry,e.protocol);if(r===null)throw Error(`Connection "${t}" is missing a ${e.protocol===`mcp`?`mcp.url`:`openapi.spec`} endpoint for protocol "${e.protocol}".`);let i=join(e.projectRoot,USER_AUTHORED_CONNECTION_DIR,`${t}.ts`),a=envKeysForAuth(n),o=await pathExists(i);if(!e.force&&o)return{slug:t,protocol:e.protocol,action:`skipped`,filePath:i,filesWritten:[],filesSkipped:[i],packageJsonUpdated:[],envKeysAdded:[],envKeysRequired:a};let s=[];if(n.kind===`connect`){let t=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.5.2`);s.push(...await ensureConnectDependency(join(e.projectRoot,`package.json`),t))}await writeTextFile(i,renderTemplate(e.protocol,r,e.entry.description,n),{force:!0});let c=await seedEnvPlaceholders(join(e.projectRoot,`.env.local`),a),l={slug:t,protocol:e.protocol,action:o?`overwritten`:`created`,filePath:i,filesWritten:[i],filesSkipped:[],packageJsonUpdated:s,envKeysAdded:c,envKeysRequired:a};return o&&(l.filesOverwritten=[i]),l}async function listAuthoredConnections(e){let t=join(e,USER_AUTHORED_CONNECTION_DIR),n;try{n=await readdir(t,{withFileTypes:!0})}catch(e){if(e.code===`ENOENT`)return[];throw e}let r=[];for(let e of n){if(e.isFile()){let t=getSupportedModuleBaseName(e.name);t!==null&&r.push(t);continue}if(e.isDirectory())try{(await readdir(join(t,e.name))).some(e=>matchesSupportedModuleBaseName(e,`connection`))&&r.push(e.name)}catch{}}return r.sort()}export{ensureConnection,ensureConnectionDependencies,listAuthoredConnections};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const DEFAULT_CONNECT_PACKAGE_VERSION = "2.2
|
|
1
|
+
export declare const DEFAULT_CONNECT_PACKAGE_VERSION = "2.5.2";
|
|
2
2
|
export declare const DEFAULT_MICROSANDBOX_PACKAGE_VERSION = "0.5.5";
|
|
3
3
|
/**
|
|
4
4
|
* Returns a scaffold version value, resolving a build-stamp token at the point
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{existsSync,readFileSync,realpathSync}from"node:fs";import{dirname,join}from"node:path";import{fileURLToPath}from"node:url";function versionToken(e){return`__${e}_VERSION__`}function bareToken(e){return`__${e}__`}const NODE_ENGINE_TOKEN=bareToken(`NODE_ENGINE`),DEFAULT_CONNECT_PACKAGE_VERSION=`2.2
|
|
1
|
+
import{existsSync,readFileSync,realpathSync}from"node:fs";import{dirname,join}from"node:path";import{fileURLToPath}from"node:url";function versionToken(e){return`__${e}_VERSION__`}function bareToken(e){return`__${e}__`}const NODE_ENGINE_TOKEN=bareToken(`NODE_ENGINE`),DEFAULT_CONNECT_PACKAGE_VERSION=`2.5.2`,DEFAULT_MICROSANDBOX_PACKAGE_VERSION=`0.5.5`,TOKEN_SOURCES={[versionToken(`EVE_PACKAGE`)]:{kind:`eve-version`},[versionToken(`EVE_PACKAGE_DEPENDENCY`)]:{kind:`eve-version`},[NODE_ENGINE_TOKEN]:{kind:`eve-node-engine`},[versionToken(`AI_SDK`)]:{kind:`catalog`,packageName:`ai`},[versionToken(`NEXT`)]:{kind:`catalog`,packageName:`next`},[versionToken(`REACT`)]:{kind:`catalog`,packageName:`react`},[versionToken(`REACT_DOM`)]:{kind:`catalog`,packageName:`react-dom`},[versionToken(`STREAMDOWN`)]:{kind:`catalog`,packageName:`streamdown`},[versionToken(`ZOD`)]:{kind:`catalog`,packageName:`zod`},[versionToken(`TYPESCRIPT`)]:{kind:`catalog`,packageName:`typescript`},[versionToken(`TYPES_REACT`)]:{kind:`catalog`,packageName:`@types/react`},[versionToken(`TYPES_REACT_DOM`)]:{kind:`catalog`,packageName:`@types/react-dom`}},resolvedTokens=new Map;function findEvePackageRoot(){let e=dirname(realpathSync(fileURLToPath(import.meta.url)));for(;;){let t=join(e,`package.json`);if(existsSync(t)&&JSON.parse(readFileSync(t,`utf8`)).name===`eve`)return e;let n=dirname(e);if(n===e)return;e=n}}function findWorkspaceManifest(e){let t=e;for(;;){let e=join(t,`pnpm-workspace.yaml`);if(existsSync(e))return e;let n=dirname(t);if(n===t)return;t=n}}function readCatalogVersion(e,t){let n=readFileSync(e,`utf8`).split(/\r?\n/),r=!1;for(let e of n){if(/^catalog:\s*$/.test(e)){r=!0;continue}if(!r)continue;if(/^\S/.test(e))break;let n=e.match(/^\s+(?:"([^"]+)"|([\w@/.-]+)):\s*"([^"]+)"/);if(n&&(n[1]??n[2])===t)return n[3]}}function resolveTokenFromDevTree(e){let t=TOKEN_SOURCES[e];if(t!==void 0)try{let e=findEvePackageRoot();if(e===void 0||!existsSync(join(e,`scripts/stamp-version-tokens.mjs`)))return;if(t.kind===`eve-version`){let t=JSON.parse(readFileSync(join(e,`package.json`),`utf8`));return typeof t.version==`string`?t.version:void 0}if(t.kind===`eve-node-engine`){let t=JSON.parse(readFileSync(join(e,`package.json`),`utf8`)).engines?.node;return typeof t==`string`?t:void 0}let n=findWorkspaceManifest(e);return n===void 0?void 0:readCatalogVersion(n,t.packageName)}catch{return}}function resolveVersionToken(e,t){if(!t.startsWith(`__`))return t;let n=resolvedTokens.get(t);if(n!==void 0)return n;let r=resolveTokenFromDevTree(t);if(r===void 0)throw Error(`Scaffold received unstamped version token (${e}=${t}). Build eve before using its dist entrypoint.`);return resolvedTokens.set(t,r),r}export{DEFAULT_CONNECT_PACKAGE_VERSION,DEFAULT_MICROSANDBOX_PACKAGE_VERSION,resolveVersionToken};
|
|
@@ -267,20 +267,28 @@ export interface AgentWorkflowDefinition {
|
|
|
267
267
|
* Applied to every run that owns the session, including successors created
|
|
268
268
|
* by deployment handoff.
|
|
269
269
|
*
|
|
270
|
-
*
|
|
270
|
+
* When omitted, eve uses the session's resolved OTel trace decision: full
|
|
271
|
+
* input and output capture keeps the World's default; dropped traces or
|
|
272
|
+
* either excluded content direction request `0`. Destination export filters
|
|
273
|
+
* and lifecycle-provider policies do not affect this choice.
|
|
274
|
+
*
|
|
275
|
+
* An explicit value overrides this automatic choice:
|
|
276
|
+
* - `"default"`: the Workflow SDK World decides, regardless of tracing.
|
|
271
277
|
* On Vercel this follows your team's plan.
|
|
272
278
|
* - `0`: the world deletes run payloads and stream chunks as soon as the run
|
|
273
279
|
* completes or fails. Metadata such as run IDs, status, and timestamps may
|
|
274
280
|
* persist up to the default period.
|
|
275
281
|
*
|
|
276
|
-
* The World
|
|
277
|
-
*
|
|
282
|
+
* The World enforces deletion. Worlds older than spec version 4 reject `0`;
|
|
283
|
+
* spec version 4 Worlds without retention support keep the data. Run, step,
|
|
284
|
+
* and event metadata and attributes remain for the default period. Exported
|
|
285
|
+
* traces are not deleted.
|
|
278
286
|
*
|
|
279
287
|
* Note that with retention set to `0`, data deletion can race reads of a finished
|
|
280
288
|
* run, so results and transcripts of completed sessions generally become
|
|
281
289
|
* unreadable. Persist anything you need to keep from inside a tool.
|
|
282
290
|
*
|
|
283
|
-
* @default
|
|
291
|
+
* @default Derived from the session's resolved trace policy.
|
|
284
292
|
*/
|
|
285
293
|
readonly retention?: AgentWorkflowRetentionDefinition;
|
|
286
294
|
/**
|