eve 0.54.2 → 0.54.4
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 +22 -0
- package/dist/src/cli/commands/init-agent-workspace.js +1 -1
- package/dist/src/cli/commands/init-project.d.ts +46 -0
- package/dist/src/cli/commands/init-project.js +1 -0
- package/dist/src/cli/commands/init-self-modification.d.ts +7 -0
- package/dist/src/cli/commands/init-self-modification.js +1 -0
- package/dist/src/cli/commands/init-target.js +2 -2
- package/dist/src/cli/commands/init-telemetry.d.ts +6 -0
- package/dist/src/cli/commands/init-telemetry.js +1 -0
- package/dist/src/cli/commands/init.d.ts +3 -0
- package/dist/src/cli/commands/init.js +1 -1
- package/dist/src/cli/dev/tui/setup-commands.js +1 -1
- package/dist/src/cli/telemetry/index.d.ts +1 -1
- package/dist/src/compiled/.vendor-stamp.json +8 -6
- package/dist/src/compiled/@ai-sdk/anthropic/index.js +2 -2
- package/dist/src/compiled/@ai-sdk/google/index.js +7 -7
- package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
- package/dist/src/compiled/@ai-sdk/openai/index.js +4 -4
- package/dist/src/compiled/@opentelemetry/api/index.d.ts +2 -0
- package/dist/src/compiled/@workflow/core/events-consumer.d.ts +26 -0
- package/dist/src/compiled/@workflow/core/flushable-stream.d.ts +41 -0
- package/dist/src/compiled/@workflow/core/index.js +2 -2
- package/dist/src/compiled/@workflow/core/replay-divergence.d.ts +25 -0
- package/dist/src/compiled/@workflow/core/runtime/helpers.d.ts +75 -1
- package/dist/src/compiled/@workflow/core/runtime/quickjs-entrypoint.d.ts +30 -8
- package/dist/src/compiled/@workflow/core/runtime/quickjs-log-view.d.ts +129 -0
- package/dist/src/compiled/@workflow/core/runtime/step-executor.d.ts +2 -21
- package/dist/src/compiled/@workflow/core/runtime/suspension-handler.d.ts +0 -22
- package/dist/src/compiled/@workflow/core/runtime.js +3 -3
- package/dist/src/compiled/@workflow/core/serialization.d.ts +2 -2
- package/dist/src/compiled/@workflow/core/step/context-storage.d.ts +2 -0
- package/dist/src/compiled/@workflow/core/telemetry/semantic-conventions.d.ts +36 -0
- package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/workflow.js +1 -1
- package/dist/src/compiled/@workflow/world/analytics.d.ts +23 -23
- package/dist/src/compiled/@workflow/world/events.d.ts +4 -2
- package/dist/src/compiled/@workflow/world/queue.d.ts +84 -0
- package/dist/src/compiled/@workflow/world-local/index.js +5 -5
- package/dist/src/compiled/@workflow/world-vercel/index.js +18 -13
- package/dist/src/compiled/_chunks/workflow/attribute-changes-BAcgmlXp.js +20 -0
- package/dist/src/compiled/_chunks/workflow/coerce-ro2dOxbr.js +1 -0
- package/dist/src/compiled/_chunks/workflow/dist-KPieTJHT.js +25 -0
- package/dist/src/compiled/_chunks/workflow/dist-PLkAQ-U7.js +2 -0
- package/dist/src/compiled/_chunks/workflow/frames-BvATzM2t.js +3 -0
- package/dist/src/compiled/_chunks/workflow/{functions-C02-JHBK.js → functions-wMCGZAVk.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/resume-hook-BEHe0Uut.js +1 -0
- package/dist/src/compiled/_chunks/workflow/run-ChHLjaCt.js +1 -0
- package/dist/src/compiled/_chunks/workflow/schemas-DR7NTzNe.js +50 -0
- package/dist/src/compiled/_chunks/workflow/sleep-BB2HuVie.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{wrapper-BxECO5nh.js → wrapper-CKui_eTd.js} +2 -2
- package/dist/src/compiled/_chunks/workflow/ws-transport-CVezyWwZ.js +1 -0
- package/dist/src/compiled/just-secrets/LICENSE +21 -0
- package/dist/src/compiled/just-secrets/index.d.ts +20 -0
- package/dist/src/compiled/just-secrets/index.js +2 -0
- package/dist/src/compiled/just-secrets/windows.ps1 +138 -0
- package/dist/src/compiler/extension-compatibility.d.ts +12 -12
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/compiler/normalize-manifest-helpers.d.ts +2 -1
- package/dist/src/compiler/normalize-manifest-helpers.js +1 -1
- package/dist/src/compiler/normalize-manifest.js +1 -1
- package/dist/src/compiler/resolve-workspace-subagent.d.ts +13 -0
- package/dist/src/compiler/resolve-workspace-subagent.js +1 -0
- package/dist/src/context/dynamic-model-lifecycle.d.ts +0 -6
- package/dist/src/context/dynamic-model-lifecycle.js +1 -1
- package/dist/src/context/dynamic-resolve-context.js +1 -1
- package/dist/src/context/effective-model.d.ts +5 -0
- package/dist/src/context/effective-model.js +1 -0
- package/dist/src/context/keys.d.ts +2 -0
- package/dist/src/context/keys.js +1 -1
- package/dist/src/dynamic/definition.d.ts +4 -0
- package/dist/src/eve-channel/index.js +1 -1
- package/dist/src/eve-channel/types.d.ts +9 -7
- package/dist/src/execution/durable-session-migrations/snapshot.d.ts +0 -16
- package/dist/src/execution/durable-session-migrations/snapshot.js +1 -1
- package/dist/src/execution/eve-workflow-attributes.d.ts +1 -1
- package/dist/src/execution/run-session-limits.js +1 -1
- package/dist/src/execution/session.js +1 -1
- package/dist/src/execution/tools/sleep-workflow.js +1 -1
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/harness/compaction.js +1 -1
- package/dist/src/harness/messages.d.ts +1 -1
- package/dist/src/harness/messages.js +1 -1
- package/dist/src/harness/step-hooks.d.ts +16 -10
- package/dist/src/harness/step-hooks.js +1 -1
- package/dist/src/harness/tool-loop.js +2 -2
- package/dist/src/instrumentation/parent-lineage.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/nitro/routes/index.d.ts +6 -0
- package/dist/src/internal/nitro/routes/index.js +7 -7
- package/dist/src/internal/vercel/assemble-eve-services.js +1 -1
- package/dist/src/internal/vercel/build-agent-workspace.js +1 -1
- package/dist/src/internal/vercel/build-multi-agent-landing-page.d.ts +3 -0
- package/dist/src/internal/vercel/build-multi-agent-landing-page.js +1 -0
- package/dist/src/internal/vercel/eve-service-contribution.d.ts +4 -0
- package/dist/src/internal/vercel/eve-service-contribution.js +1 -1
- package/dist/src/internal/vercel/vercel-services-config.js +1 -1
- package/dist/src/protocol/baggage.d.ts +6 -0
- package/dist/src/protocol/baggage.js +1 -1
- package/dist/src/protocol/traceparent.d.ts +13 -0
- package/dist/src/protocol/traceparent.js +1 -1
- package/dist/src/public/definitions/workspace-agent.d.ts +25 -0
- package/dist/src/public/definitions/workspace-agent.js +1 -0
- package/dist/src/public/index.d.ts +1 -0
- package/dist/src/public/index.js +1 -1
- package/dist/src/public/models/openai/chatgpt/codex-app-server.d.ts +41 -0
- package/dist/src/public/models/openai/chatgpt/codex-app-server.js +1 -0
- package/dist/src/public/models/openai/chatgpt/credential-store.d.ts +26 -4
- package/dist/src/public/models/openai/chatgpt/credential-store.js +1 -1
- package/dist/src/public/models/openai/chatgpt/oauth.d.ts +6 -4
- package/dist/src/public/models/openai/chatgpt/token-broker.d.ts +7 -7
- package/dist/src/public/models/openai/chatgpt/token-broker.js +1 -1
- package/dist/src/public/models/openai/chatgpt/token.d.ts +13 -0
- package/dist/src/public/models/openai/chatgpt/token.js +1 -0
- package/dist/src/public/models/openai/chatgpt/transport.d.ts +2 -1
- package/dist/src/public/models/openai/index.d.ts +3 -2
- package/dist/src/public/vercel/index.d.ts +50 -0
- package/dist/src/public/vercel/index.js +1 -0
- package/dist/src/self-modification/setup.js +7 -2
- package/dist/src/setup/flows/chatgpt-auth.d.ts +2 -1
- package/dist/src/setup/flows/chatgpt-auth.js +1 -1
- package/dist/src/setup/flows/model.d.ts +0 -2
- package/dist/src/setup/flows/model.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/subagents/remote-dispatch.d.ts +3 -1
- package/dist/src/subagents/remote-dispatch.js +1 -1
- package/dist/src/tracing/agent-otel-attributes.js +1 -1
- package/dist/src/tracing/agent-otel-runtime-context.js +1 -1
- package/docs/agent-config.md +3 -3
- package/docs/guides/deployment/vercel.mdx +52 -1
- package/docs/guides/dynamic-capabilities.md +19 -7
- package/docs/guides/instrumentation-providers.md +1 -1
- package/docs/guides/instrumentation.md +25 -6
- package/docs/guides/remote-agents.md +5 -5
- package/docs/reference/cli.md +2 -2
- package/docs/reference/telemetry.md +1 -1
- package/docs/reference/typescript-api.md +14 -7
- package/docs/subagents/index.mdx +31 -0
- package/package.json +13 -6
- package/dist/src/compiled/_chunks/workflow/attribute-changes-C6H-fRVP.js +0 -20
- package/dist/src/compiled/_chunks/workflow/dist-DDeH-1ER.js +0 -40
- package/dist/src/compiled/_chunks/workflow/dist-DhncQSl7.js +0 -74
- package/dist/src/compiled/_chunks/workflow/frames-DsEqSDes.js +0 -3
- package/dist/src/compiled/_chunks/workflow/resume-hook-BRDLAb67.js +0 -1
- package/dist/src/compiled/_chunks/workflow/run-BM2OFphk.js +0 -1
- package/dist/src/compiled/_chunks/workflow/sleep-6cG0F99-.js +0 -1
- package/dist/src/compiled/_chunks/workflow/ws-transport-DuK82LLz.js +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const AGENT_NAME_PLACEHOLDER=`{{AGENT_NAME}}`,STATUS_DETAIL_PLACEHOLDER=`{{STATUS_DETAIL}}`,TERMINAL_PLACEHOLDER=`{{TERMINAL}}`,HOME_PAGE_HTML_TEMPLATE=`<!doctype html>
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8">
|
|
@@ -170,13 +170,13 @@ const DEPLOYMENT_URL_PLACEHOLDER=`{{DEPLOYMENT_URL}}`,AGENT_NAME_PLACEHOLDER=`{{
|
|
|
170
170
|
<div class="agent-row">
|
|
171
171
|
<strong class="agent-name">${AGENT_NAME_PLACEHOLDER}</strong>
|
|
172
172
|
</div>
|
|
173
|
-
<p class="lede"><span class="status"><span class="status-dot" aria-hidden="true"></span>Ready</span><span class="lede-divider" aria-hidden="true">/</span><span
|
|
174
|
-
|
|
175
|
-
<span class="terminal-prompt" aria-hidden="true">$</span>
|
|
176
|
-
<span class="terminal-cmd">eve dev ${DEPLOYMENT_URL_PLACEHOLDER}</span>
|
|
177
|
-
</div>
|
|
173
|
+
<p class="lede"><span class="status"><span class="status-dot" aria-hidden="true"></span>Ready</span><span class="lede-divider" aria-hidden="true">/</span><span>${STATUS_DETAIL_PLACEHOLDER}</span> <a href="https://eve.dev/docs">Docs<span class="lede-arrow" aria-hidden="true"> →</span></a></p>
|
|
174
|
+
${TERMINAL_PLACEHOLDER}
|
|
178
175
|
</section>
|
|
179
176
|
</main>
|
|
180
177
|
</body>
|
|
181
178
|
</html>
|
|
182
|
-
`;function escapeHtml(e){return e.replaceAll(`&`,`&`).replaceAll(`<`,`<`).replaceAll(`>`,`>`).replaceAll(`"`,`"`).replaceAll(`'`,`'`)}function pickFirstForwardedValue(e){if(e===null)return;let t=e.split(`,`)[0]?.trim();if(t!==void 0&&t.length!==0)return t}function resolveDeploymentUrl(e){let t=e.headers,n=new URL(e.url),r=pickFirstForwardedValue(t.get(`x-forwarded-host`)),i=pickFirstForwardedValue(t.get(`x-forwarded-proto`)),a=r??t.get(`host`)??n.host;return`${i??n.protocol.replace(/:$/,``)}://${a}`}function
|
|
179
|
+
`;function escapeHtml(e){return e.replaceAll(`&`,`&`).replaceAll(`<`,`<`).replaceAll(`>`,`>`).replaceAll(`"`,`"`).replaceAll(`'`,`'`)}function pickFirstForwardedValue(e){if(e===null)return;let t=e.split(`,`)[0]?.trim();if(t!==void 0&&t.length!==0)return t}function resolveDeploymentUrl(e){let t=e.headers,n=new URL(e.url),r=pickFirstForwardedValue(t.get(`x-forwarded-host`)),i=pickFirstForwardedValue(t.get(`x-forwarded-proto`)),a=r??t.get(`host`)??n.host;return`${i??n.protocol.replace(/:$/,``)}://${a}`}function buildHomePageHtml(e){let t=e.terminalCommand===void 0?``:`<div class="terminal mono" role="group" aria-label="Send a message from your terminal">
|
|
180
|
+
<span class="terminal-prompt" aria-hidden="true">$</span>
|
|
181
|
+
<span class="terminal-cmd">${escapeHtml(e.terminalCommand)}</span>
|
|
182
|
+
</div>`;return HOME_PAGE_HTML_TEMPLATE.replace(AGENT_NAME_PLACEHOLDER,()=>escapeHtml(e.name)).replace(STATUS_DETAIL_PLACEHOLDER,()=>escapeHtml(e.statusDetail)).replace(TERMINAL_PLACEHOLDER,()=>t)}function buildHomePageResponse(e,t){let n=resolveDeploymentUrl(t),r=buildHomePageHtml({name:e.agentName,statusDetail:`Agent is up and accepting messages.`,terminalCommand:`eve dev ${n}`});return new Response(r,{headers:{"cache-control":`no-store`,"content-type":`text/html; charset=utf-8`}})}export{buildHomePageHtml,buildHomePageResponse};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{findConfiguredEveServiceEntry,insertEveServiceRequestPathRoute,insertEveServiceRoutes}from"#internal/vercel/vercel-service-config-operations.js";import{compileEveVercelService}from"#internal/vercel/eve-service-contribution.js";function assembleEveVercelServices(e){let t=e.services??{},n={...t},r=[],i=[];for(let{agent:a,target:o}of e.agents){let e=compileEveVercelService({agent:a,target:o}),s=findConfiguredEveServiceEntry(t,a),c=s?.name??e.serviceName;s===void 0&&r.push(e.rootDirectory),n[c]=s===void 0?e.service:{...s.service,routes:insertEveServiceRequestPathRoute(s.service.routes,e.routeSrc)},i.push({routeSrc:e.routeSrc,serviceName:c})}return{rootDirectories:r,routes:insertEveServiceRoutes(e.routes??[],i),services:n}}export{assembleEveVercelServices};
|
|
1
|
+
import{findConfiguredEveServiceEntry,insertEveServiceRequestPathRoute,insertEveServiceRoutes}from"#internal/vercel/vercel-service-config-operations.js";import{compileEveVercelService}from"#internal/vercel/eve-service-contribution.js";function assembleEveVercelServices(e){let t=e.services??{},n={...t},r=[],i=[];for(let{agent:a,target:o}of e.agents){let e=compileEveVercelService({agent:a,target:o}),s=findConfiguredEveServiceEntry(t,a),c=s?.name??e.serviceName;s===void 0&&r.push(e.rootDirectory),n[c]=s===void 0?e.service:{...s.service,routes:insertEveServiceRequestPathRoute(s.service.routes,e.routeSrc)},i.push({routeSrc:e.routeSrc,serviceName:c}),e.homeRouteSrc!==void 0&&i.push({routeSrc:e.homeRouteSrc,serviceName:c})}return{rootDirectories:r,routes:insertEveServiceRoutes(e.routes??[],i),services:n}}export{assembleEveVercelServices};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{mkdir,rm,writeFile}from"node:fs/promises";import{join,relative}from"node:path";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{VERCEL_EVE_AGENT_SUMMARY_OUTPUT_PATH,VERCEL_EVE_MULTI_AGENT_SUMMARY_KIND,VERCEL_EVE_MULTI_AGENT_SUMMARY_VERSION}from"#internal/vercel-agent-summary.js";import{readVercelJsonFile}from"#internal/vercel/vercel-services-config.js";import{assembleEveVercelServices}from"#internal/vercel/assemble-eve-services.js";import{quoteVercelShellArgument,toVercelRelativePath}from"#internal/vercel/build-command.js";import{resolveEveBinaryPath}from"#shared/resolve-eve-binary.js";function createMultiAgentSummary(e){return{agents:e.members.map(t=>({name:t.name,routePrefix:`/${t.name}`,summaryPath:relative(e.root,join(t.appRoot,VERCEL_EVE_AGENT_SUMMARY_OUTPUT_PATH)).replaceAll(`\\`,`/`)})),generatorVersion:resolveInstalledPackageInfo().version,kind:VERCEL_EVE_MULTI_AGENT_SUMMARY_KIND,schemaVersion:VERCEL_EVE_MULTI_AGENT_SUMMARY_VERSION}}async function buildAgentWorkspace(e){let t=await readVercelJsonFile(join(e.root,`vercel.json`));if(t.services!==void 0||t.experimentalServices!==void 0||t.experimentalServicesV2!==void 0)throw Error("This project defines its Vercel service graph in vercel.json.
|
|
1
|
+
import{mkdir,rm,writeFile}from"node:fs/promises";import{join,relative}from"node:path";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{VERCEL_EVE_AGENT_SUMMARY_OUTPUT_PATH,VERCEL_EVE_MULTI_AGENT_SUMMARY_KIND,VERCEL_EVE_MULTI_AGENT_SUMMARY_VERSION}from"#internal/vercel-agent-summary.js";import{readVercelJsonFile}from"#internal/vercel/vercel-services-config.js";import{assembleEveVercelServices}from"#internal/vercel/assemble-eve-services.js";import{buildMultiAgentLandingPage}from"#internal/vercel/build-multi-agent-landing-page.js";import{quoteVercelShellArgument,toVercelRelativePath}from"#internal/vercel/build-command.js";import{resolveEveBinaryPath}from"#shared/resolve-eve-binary.js";function createMultiAgentSummary(e){return{agents:e.members.map(t=>({name:t.name,routePrefix:`/${t.name}`,summaryPath:relative(e.root,join(t.appRoot,VERCEL_EVE_AGENT_SUMMARY_OUTPUT_PATH)).replaceAll(`\\`,`/`)})),generatorVersion:resolveInstalledPackageInfo().version,kind:VERCEL_EVE_MULTI_AGENT_SUMMARY_KIND,schemaVersion:VERCEL_EVE_MULTI_AGENT_SUMMARY_VERSION}}async function buildAgentWorkspace(e){let t=await readVercelJsonFile(join(e.root,`vercel.json`));if(t.services!==void 0||t.experimentalServices!==void 0||t.experimentalServicesV2!==void 0)throw Error("This project defines its Vercel service graph in vercel.json. Compose generated workspace agents from a programmatic vercel.ts with `withEve` from `eve/vercel`, manually define every service and run `vercel build`, or run `eve build` from an individual agent directory.");let n=e.members.map(t=>({agent:{appRoot:t.appRoot,buildCommand:`node ${quoteVercelShellArgument(toVercelRelativePath(t.appRoot,resolveEveBinaryPath(t.appRoot)))} build`,name:t.name,publicRoutePrefix:`/${t.name}`,workspaceMember:!0},target:{hostOutputDirectory:join(e.root,`.vercel`,`output`),projectRoot:e.root}})),r=assembleEveVercelServices({agents:n}),i=join(e.root,`.vercel`,`output`);await rm(i,{force:!0,recursive:!0}),await mkdir(i,{recursive:!0}),await Promise.all(r.rootDirectories.map(e=>mkdir(e,{recursive:!0}))),await mkdir(join(e.root,`.eve`),{recursive:!0}),await writeFile(join(e.root,VERCEL_EVE_AGENT_SUMMARY_OUTPUT_PATH),`${JSON.stringify(createMultiAgentSummary(e),null,2)}\n`);let a=join(i,`static`);return await mkdir(a,{recursive:!0}),await writeFile(join(a,`index.html`),buildMultiAgentLandingPage(e)),await writeFile(join(i,`config.json`),`${JSON.stringify({version:3,routes:[...r.routes,{handle:`filesystem`}],services:r.services},null,2)}\n`),i}export{buildAgentWorkspace};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{buildHomePageHtml}from"#internal/nitro/routes/index.js";function buildMultiAgentLandingPage(e){let t=e.members.length;return buildHomePageHtml({name:`eve agents`,statusDetail:`${t} ${t===1?`agent is`:`agents are`} up and accepting messages.`})}export{buildMultiAgentLandingPage};
|
|
@@ -11,6 +11,7 @@ export interface EveVercelBuildTarget {
|
|
|
11
11
|
readonly projectRoot: string;
|
|
12
12
|
}
|
|
13
13
|
export interface EveVercelServiceContribution {
|
|
14
|
+
readonly homeRouteSrc: string | undefined;
|
|
14
15
|
readonly rootDirectory: string;
|
|
15
16
|
readonly routeSrc: string;
|
|
16
17
|
readonly service: GeneratedVercelServiceConfig;
|
|
@@ -20,6 +21,9 @@ export interface EveVercelServiceContribution {
|
|
|
20
21
|
export declare function createEveServiceName(name: string | undefined): string;
|
|
21
22
|
export declare function createEveServiceRouteSrc(publicRoutePrefix: string): string;
|
|
22
23
|
export declare function createEveRequestPathRoute(routeSrc: string): VercelRouteConfig;
|
|
24
|
+
export declare function createEveHomeRouteSrc(publicRoutePrefix: string): string | undefined;
|
|
25
|
+
/** Route a member's public base path to its package-owned home channel. */
|
|
26
|
+
export declare function createEveHomePathRoute(publicRoutePrefix: string): VercelRouteConfig | undefined;
|
|
23
27
|
export declare function createEvePublicRoute(serviceName: string, routeSrc: string): VercelRouteConfig;
|
|
24
28
|
/** Compile one eve agent into its complete Vercel service and ingress contribution. */
|
|
25
29
|
export declare function compileEveVercelService(input: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHash}from"node:crypto";import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";import{join}from"node:path";import{EVE_INTERNAL_AGENT_WORKSPACE_MEMBER_ENV,EVE_INTERNAL_BUILD_OUTPUT_DIRECTORY_ENV,EVE_INTERNAL_HOST_BUILD_OUTPUT_DIRECTORY_ENV}from"#internal/application/build-output-environment.js";import{EVE_PUBLIC_ROUTE_PREFIX_ENV,normalizePublicRoutePrefix}from"#shared/public-route-prefix.js";import{quoteVercelShellArgument,toVercelRelativePath}from"#internal/vercel/build-command.js";import{MAX_VERCEL_SERVICE_NAME_LENGTH,assertValidVercelServiceName,isValidVercelServiceName}from"#internal/vercel/vercel-service-name.js";function createServiceNameHash(e){return[...createHash(`sha256`).update(e).digest().subarray(0,10)].map(e=>String.fromCharCode(97+e%26)).join(``)}function createEveServiceName(e){if(e===void 0)return`eve`;let t=`eve-${e}`;if(isValidVercelServiceName(t))return t;let n=createServiceNameHash(e),r=e.replace(/[^a-z_-]+/g,`-`).replace(/^[^a-z]+|[^a-z]+$/g,``)||`agent`,i=MAX_VERCEL_SERVICE_NAME_LENGTH-5-n.length,a=`eve-${r.slice(0,i).replace(/[^a-z]+$/g,``)||`agent`}-${n}`;return assertValidVercelServiceName(a,`Generated eve service name`),a}function createEveServiceRouteSrc(e){return e.length===0?`^${EVE_ROUTE_PREFIX}/(.*)$`:`^${(e.startsWith(`/`)?e:`/${e}`)
|
|
1
|
+
import{createHash}from"node:crypto";import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";import{join}from"node:path";import{EVE_INTERNAL_AGENT_WORKSPACE_MEMBER_ENV,EVE_INTERNAL_BUILD_OUTPUT_DIRECTORY_ENV,EVE_INTERNAL_HOST_BUILD_OUTPUT_DIRECTORY_ENV}from"#internal/application/build-output-environment.js";import{EVE_PUBLIC_ROUTE_PREFIX_ENV,normalizePublicRoutePrefix}from"#shared/public-route-prefix.js";import{quoteVercelShellArgument,toVercelRelativePath}from"#internal/vercel/build-command.js";import{MAX_VERCEL_SERVICE_NAME_LENGTH,assertValidVercelServiceName,isValidVercelServiceName}from"#internal/vercel/vercel-service-name.js";function createServiceNameHash(e){return[...createHash(`sha256`).update(e).digest().subarray(0,10)].map(e=>String.fromCharCode(97+e%26)).join(``)}function createEveServiceName(e){if(e===void 0)return`eve`;let t=`eve-${e}`;if(isValidVercelServiceName(t))return t;let n=createServiceNameHash(e),r=e.replace(/[^a-z_-]+/g,`-`).replace(/^[^a-z]+|[^a-z]+$/g,``)||`agent`,i=MAX_VERCEL_SERVICE_NAME_LENGTH-5-n.length,a=`eve-${r.slice(0,i).replace(/[^a-z]+$/g,``)||`agent`}-${n}`;return assertValidVercelServiceName(a,`Generated eve service name`),a}function escapeVercelRouteLiteral(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function createEveServiceRouteSrc(e){return e.length===0?`^${EVE_ROUTE_PREFIX}/(.*)$`:`^${escapeVercelRouteLiteral(e.startsWith(`/`)?e:`/${e}`)}${EVE_ROUTE_PREFIX}/(.*)$`}function createEveRequestPathRoute(e){return{src:e,transforms:[{args:`${EVE_ROUTE_PREFIX}/$1`,op:`set`,type:`request.path`}]}}function createEveHomeRouteSrc(e){return e.length===0?void 0:`^${escapeVercelRouteLiteral(e.startsWith(`/`)?e:`/${e}`)}/?$`}function createEveHomePathRoute(e){let t=createEveHomeRouteSrc(e);return t===void 0?void 0:{src:t,transforms:[{args:`/`,op:`set`,type:`request.path`}]}}function createEvePublicRoute(e,t){return{destination:{service:e,type:`service`},src:t}}function createIsolatedBuild(e){let t=join(e.projectRoot,`.eve/vercel-services`,e.serviceName),n=join(t,`.vercel`,`output`),r=normalizePublicRoutePrefix(e.agent.publicRoutePrefix),i=r===void 0?``:` && export ${EVE_PUBLIC_ROUTE_PREFIX_ENV}=${quoteVercelShellArgument(r)}`,a=e.agent.workspaceMember===!0?` && export ${EVE_INTERNAL_AGENT_WORKSPACE_MEMBER_ENV}=1`:``;return{buildCommand:`cd ${quoteVercelShellArgument(toVercelRelativePath(t,e.agent.appRoot))} && export ${EVE_INTERNAL_BUILD_OUTPUT_DIRECTORY_ENV}=${quoteVercelShellArgument(toVercelRelativePath(e.agent.appRoot,n))} && export ${EVE_INTERNAL_HOST_BUILD_OUTPUT_DIRECTORY_ENV}=${quoteVercelShellArgument(toVercelRelativePath(e.agent.appRoot,e.hostOutputDirectory))}${i}${a} && ${e.agent.buildCommand}`,root:toVercelRelativePath(e.projectRoot,t),rootDirectory:t}}function compileEveVercelService(e){let t=createEveServiceName(e.agent.name),n=createEveServiceRouteSrc(e.agent.publicRoutePrefix),r=e.agent.workspaceMember===!0?createEveHomeRouteSrc(e.agent.publicRoutePrefix):void 0,i=e.agent.workspaceMember===!0?createEveHomePathRoute(e.agent.publicRoutePrefix):void 0,a=createIsolatedBuild({agent:e.agent,hostOutputDirectory:e.target.hostOutputDirectory,projectRoot:e.target.projectRoot,serviceName:t});return{homeRouteSrc:r,rootDirectory:a.rootDirectory,routeSrc:n,service:{buildCommand:a.buildCommand,framework:`eve`,root:a.root,routes:[...i===void 0?[]:[i],createEveRequestPathRoute(n)],...e.agent.publicRoutePrefix.length>0?{routePrefix:e.agent.publicRoutePrefix}:{}},serviceName:t}}export{compileEveVercelService,createEveHomePathRoute,createEveHomeRouteSrc,createEvePublicRoute,createEveRequestPathRoute,createEveServiceName,createEveServiceRouteSrc};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readFile}from"node:fs/promises";import{parseJsonObject}from"#shared/json.js";function optionalString(e,t){if(e!==void 0){if(typeof e!=`string`)throw Error(`${t} must be a string.`);return e}}function objectValue(e,t){try{return parseJsonObject(e)}catch{throw Error(`${t} must contain a JSON object.`)}}function parseDestination(e,t){if(e===void 0||typeof e==`string`)return e;let n;try{n=parseJsonObject(e)}catch{throw Error(`${t} must be a string or JSON object.`)}return{...n,service:optionalString(n.service,`${t}.service`),type:optionalString(n.type,`${t}.type`)}}function parseRoute(e,t){let n=objectValue(e,t);return{...n,destination:parseDestination(n.destination,`${t}.destination`),handle:optionalString(n.handle,`${t}.handle`),src:optionalString(n.src,`${t}.src`)}}function parseArray(e,t,n){if(e!==void 0){if(!Array.isArray(e))throw Error(`${t} must be an array.`);return e.map((e,r)=>n(e,`${t}[${r}]`))}}function parseMount(e,t){if(e===void 0||typeof e==`string`)return e;let n;try{n=parseJsonObject(e)}catch{throw Error(`${t} must be a string or JSON object.`)}return{...n,path:optionalString(n.path,`${t}.path`),subdomain:optionalString(n.subdomain,`${t}.subdomain`)}}function parseServiceConfig(e,t){let n=objectValue(e,t);return{...n,buildCommand:optionalString(n.buildCommand,`${t}.buildCommand`),entrypoint:optionalString(n.entrypoint,`${t}.entrypoint`),framework:optionalString(n.framework,`${t}.framework`),mount:parseMount(n.mount,`${t}.mount`),routes:parseArray(n.routes,`${t}.routes`,parseRoute),routePrefix:optionalString(n.routePrefix,`${t}.routePrefix`),root:optionalString(n.root,`${t}.root`),type:optionalString(n.type,`${t}.type`)}}function parseServices(e,t){if(e===void 0)return;if(Array.isArray(e))return e.map((e,n)=>{let r=`${t} services[${n}]`,i=objectValue(e,r),a=optionalString(i.name,`${r}.name`);if(a===void 0||a.trim().length===0)throw Error(`${r} must have a non-empty name.`);let{name:o,...s}=i;return{...parseServiceConfig(s,r),name:a}});let n;try{n=parseJsonObject(e)}catch{throw Error(`${t} services must be a JSON object or named service array.`)}return Object.fromEntries(Object.entries(n).map(([e,n])=>[e,parseServiceConfig(n,`${t} service ${JSON.stringify(e)}`)]))}function parseVercelServicesConfig(e,t){let n;try{n=parseJsonObject(e)}catch{throw Error(`${t} must contain a JSON object.`)}return{...n,routes:parseArray(n.routes,`${t} routes`,parseRoute),services:parseServices(n.services,t)}}function isNamedServiceArray(e){return Array.isArray(e)}function createServiceConfigRecord(e){
|
|
1
|
+
import{readFile}from"node:fs/promises";import{parseJsonObject}from"#shared/json.js";function optionalString(e,t){if(e!==void 0){if(typeof e!=`string`)throw Error(`${t} must be a string.`);return e}}function objectValue(e,t){try{return parseJsonObject(e)}catch{throw Error(`${t} must contain a JSON object.`)}}function parseDestination(e,t){if(e===void 0||typeof e==`string`)return e;let n;try{n=parseJsonObject(e)}catch{throw Error(`${t} must be a string or JSON object.`)}return{...n,service:optionalString(n.service,`${t}.service`),type:optionalString(n.type,`${t}.type`)}}function parseRoute(e,t){let n=objectValue(e,t);return{...n,destination:parseDestination(n.destination,`${t}.destination`),handle:optionalString(n.handle,`${t}.handle`),src:optionalString(n.src,`${t}.src`)}}function parseArray(e,t,n){if(e!==void 0){if(!Array.isArray(e))throw Error(`${t} must be an array.`);return e.map((e,r)=>n(e,`${t}[${r}]`))}}function parseMount(e,t){if(e===void 0||typeof e==`string`)return e;let n;try{n=parseJsonObject(e)}catch{throw Error(`${t} must be a string or JSON object.`)}return{...n,path:optionalString(n.path,`${t}.path`),subdomain:optionalString(n.subdomain,`${t}.subdomain`)}}function parseServiceConfig(e,t){let n=objectValue(e,t);return{...n,buildCommand:optionalString(n.buildCommand,`${t}.buildCommand`),entrypoint:optionalString(n.entrypoint,`${t}.entrypoint`),framework:optionalString(n.framework,`${t}.framework`),mount:parseMount(n.mount,`${t}.mount`),routes:parseArray(n.routes,`${t}.routes`,parseRoute),routePrefix:optionalString(n.routePrefix,`${t}.routePrefix`),root:optionalString(n.root,`${t}.root`),type:optionalString(n.type,`${t}.type`)}}function parseServices(e,t){if(e===void 0)return;if(Array.isArray(e))return e.map((e,n)=>{let r=`${t} services[${n}]`,i=objectValue(e,r),a=optionalString(i.name,`${r}.name`);if(a===void 0||a.trim().length===0)throw Error(`${r} must have a non-empty name.`);let{name:o,...s}=i;return{...parseServiceConfig(s,r),name:a}});let n;try{n=parseJsonObject(e)}catch{throw Error(`${t} services must be a JSON object or named service array.`)}return Object.fromEntries(Object.entries(n).map(([e,n])=>[e,parseServiceConfig(n,`${t} service ${JSON.stringify(e)}`)]))}function parseVercelServicesConfig(e,t){let n;try{n=parseJsonObject(e)}catch{throw Error(`${t} must contain a JSON object.`)}return{...n,routes:parseArray(n.routes,`${t} routes`,parseRoute),services:parseServices(n.services,t)}}function isNamedServiceArray(e){return Array.isArray(e)}function createServiceConfigRecord(e){if(e===void 0)return{};if(!isNamedServiceArray(e))return e;let t={};for(let{name:n,...r}of e){if(Object.hasOwn(t,n))throw Error(`Duplicate Vercel service name ${JSON.stringify(n)}.`);t[n]=r}return t}function hasServices(e){return Object.keys(createServiceConfigRecord(e)).length>0}async function readVercelJsonFile(e){try{return parseVercelServicesConfig(JSON.parse(await readFile(e,`utf8`)),e)}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return{};throw e}}export{createServiceConfigRecord,hasServices,parseVercelServicesConfig,readVercelJsonFile};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ForwardedTraceAssertion } from "#shared/forwarded-trace-policy.js";
|
|
2
|
+
import type { SessionParent } from "#channel/types.js";
|
|
2
3
|
interface BaggageProperty {
|
|
3
4
|
readonly key: string;
|
|
4
5
|
readonly value?: string;
|
|
@@ -8,6 +9,11 @@ interface BaggageMember {
|
|
|
8
9
|
readonly properties: readonly BaggageProperty[];
|
|
9
10
|
}
|
|
10
11
|
export type ForwardedTraceBaggage = "absent" | "malformed" | ForwardedTraceAssertion;
|
|
12
|
+
export type ForwardedParentSessionBaggage = "absent" | "malformed" | SessionParent;
|
|
13
|
+
/** Reads remote parent lineage without trusting the caller that supplied it. */
|
|
14
|
+
export declare function readForwardedParentSessionBaggage(value: string | null): ForwardedParentSessionBaggage;
|
|
15
|
+
/** Replaces Eve's remote parent lineage while preserving unrelated baggage. */
|
|
16
|
+
export declare function writeForwardedParentSessionBaggage(value: string | undefined, parent: SessionParent | undefined): string | undefined;
|
|
11
17
|
/** Reads eve's audience member without interpreting unrelated baggage. */
|
|
12
18
|
export declare function readForwardedAudienceBaggage(value: string | null): ForwardedTraceBaggage;
|
|
13
19
|
/** Replaces any authored eve audience member while preserving unrelated baggage entries. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{formatTraceContentCeiling}from"#shared/forwarded-trace-policy.js";const EVE_AUDIENCE_KEY=`eve.audience`,CEILING_PROPERTY_KEY=`ceiling`,MAX_BAGGAGE_BYTES=8192,encoder=new TextEncoder,decoder=new TextDecoder(`utf-8`,{ignoreBOM:!0});function readForwardedAudienceBaggage(e){let t=readBaggageMember(e,EVE_AUDIENCE_KEY);if(typeof t==`string`)return t;let n=t.value;if(n!==`public`&&n!==`private`&&n!==`unknown`)return`malformed`;let r=t.properties[0];if(t.properties.length!==1||r?.key!==CEILING_PROPERTY_KEY)return`malformed`;let i=r.value===void 0?void 0:parseCeiling(r.value);return i===void 0?`malformed`:{ceiling:i,originAudience:n}}function writeForwardedAudienceBaggage(e,t){return replaceBaggageMember(e,EVE_AUDIENCE_KEY,t===void 0?void 0:`${t.originAudience};${CEILING_PROPERTY_KEY}=${formatTraceContentCeiling(t.ceiling)}`)}function readBaggageMember(e,t){if(e===null)return`absent`;if(e.length>MAX_BAGGAGE_BYTES||encoder.encode(e).byteLength>MAX_BAGGAGE_BYTES)return`malformed`;let n=baggageMembers(e).filter(e=>baggageKey(e)===t);if(n.length===0)return`absent`;if(n.length!==1)return`malformed`;let[r,...i]=n[0].split(`;`),a=parsePair(r);if(a?.value===void 0)return`malformed`;let o=[];for(let e of i){let t=parsePair(e);if(t===void 0)return`malformed`;o.push(t)}return{value:a.value,properties:o}}function replaceBaggageMember(e,t,n){let r=baggageMembers(e??``).filter(e=>baggageKey(e)!==t);if(n!==void 0){let e=[...r,`${t}=${n}`].join(`,`);if(encoder.encode(e).byteLength>MAX_BAGGAGE_BYTES)throw Error(`Cannot forward baggage: header exceeds 8192 bytes. Reduce remote.headers.baggage.`);return e}return r.join(`,`)||void 0}function baggageMembers(e){return e.split(`,`).map(trimOws).filter(Boolean)}function parsePair(e){let t=e.indexOf(`=`),n=trimOws(t<0?e:e.slice(0,t));if(!/^[!#$%&'*+\-.^_`|~\w]+$/u.test(n))return;if(t<0)return{key:n};let r=trimOws(e.slice(t+1));if(!/^[\x21\x23-\x2b\x2d-\x3a\x3c-\x5b\x5d-\x7e]*$/u.test(r)||/%(?![\da-f]{2})/iu.test(r))return;let i=Uint8Array.from(r.match(/%[\da-f]{2}|./giu)??[],e=>e.startsWith(`%`)?Number.parseInt(e.slice(1),16):e.charCodeAt(0));return{key:n,value:decoder.decode(i)}}function parseCeiling(e){let t=/^i([01])o([01])$/u.exec(e);return t===null?void 0:{recordInputs:t[1]===`1`,recordOutputs:t[2]===`1`}}function trimOws(e){return e.replace(/^[\t ]+|[\t ]+$/gu,``)}function baggageKey(e){let t=e.split(`;`,1)[0],n=t.indexOf(`=`);return(n<0?t:t.slice(0,n)).trim()}export{readBaggageMember,readForwardedAudienceBaggage,replaceBaggageMember,writeForwardedAudienceBaggage};
|
|
1
|
+
import{formatTraceContentCeiling}from"#shared/forwarded-trace-policy.js";const EVE_AUDIENCE_KEY=`eve.audience`,EVE_PARENT_SESSION_KEY=`eve.parent_session`,CEILING_PROPERTY_KEY=`ceiling`,MAX_BAGGAGE_BYTES=8192,encoder=new TextEncoder,decoder=new TextDecoder(`utf-8`,{ignoreBOM:!0});function readForwardedParentSessionBaggage(e){let t=readBaggageMember(e,EVE_PARENT_SESSION_KEY);if(typeof t==`string`)return t;if(t.properties.length!==0)return`malformed`;let n;try{n=JSON.parse(t.value)}catch{return`malformed`}if(typeof n!=`object`||!n||Array.isArray(n))return`malformed`;let r=n,i=r.turn;return typeof r.callId!=`string`||r.callId.length===0||typeof r.rootSessionId!=`string`||r.rootSessionId.length===0||typeof r.sessionId!=`string`||r.sessionId.length===0||i===void 0||typeof i.id!=`string`||i.id.length===0||!Number.isSafeInteger(i.sequence)||i.sequence<0?`malformed`:{callId:r.callId,rootSessionId:r.rootSessionId,sessionId:r.sessionId,turn:{id:i.id,sequence:i.sequence}}}function writeForwardedParentSessionBaggage(e,t){return replaceBaggageMember(e,EVE_PARENT_SESSION_KEY,t===void 0?void 0:encodeURIComponent(JSON.stringify(t)))}function readForwardedAudienceBaggage(e){let t=readBaggageMember(e,EVE_AUDIENCE_KEY);if(typeof t==`string`)return t;let n=t.value;if(n!==`public`&&n!==`private`&&n!==`unknown`)return`malformed`;let r=t.properties[0];if(t.properties.length!==1||r?.key!==CEILING_PROPERTY_KEY)return`malformed`;let i=r.value===void 0?void 0:parseCeiling(r.value);return i===void 0?`malformed`:{ceiling:i,originAudience:n}}function writeForwardedAudienceBaggage(e,t){return replaceBaggageMember(e,EVE_AUDIENCE_KEY,t===void 0?void 0:`${t.originAudience};${CEILING_PROPERTY_KEY}=${formatTraceContentCeiling(t.ceiling)}`)}function readBaggageMember(e,t){if(e===null)return`absent`;if(e.length>MAX_BAGGAGE_BYTES||encoder.encode(e).byteLength>MAX_BAGGAGE_BYTES)return`malformed`;let n=baggageMembers(e).filter(e=>baggageKey(e)===t);if(n.length===0)return`absent`;if(n.length!==1)return`malformed`;let[r,...i]=n[0].split(`;`),a=parsePair(r);if(a?.value===void 0)return`malformed`;let o=[];for(let e of i){let t=parsePair(e);if(t===void 0)return`malformed`;o.push(t)}return{value:a.value,properties:o}}function replaceBaggageMember(e,t,n){let r=baggageMembers(e??``).filter(e=>baggageKey(e)!==t);if(n!==void 0){let e=[...r,`${t}=${n}`].join(`,`);if(encoder.encode(e).byteLength>MAX_BAGGAGE_BYTES)throw Error(`Cannot forward baggage: header exceeds 8192 bytes. Reduce remote.headers.baggage.`);return e}return r.join(`,`)||void 0}function baggageMembers(e){return e.split(`,`).map(trimOws).filter(Boolean)}function parsePair(e){let t=e.indexOf(`=`),n=trimOws(t<0?e:e.slice(0,t));if(!/^[!#$%&'*+\-.^_`|~\w]+$/u.test(n))return;if(t<0)return{key:n};let r=trimOws(e.slice(t+1));if(!/^[\x21\x23-\x2b\x2d-\x3a\x3c-\x5b\x5d-\x7e]*$/u.test(r)||/%(?![\da-f]{2})/iu.test(r))return;let i=Uint8Array.from(r.match(/%[\da-f]{2}|./giu)??[],e=>e.startsWith(`%`)?Number.parseInt(e.slice(1),16):e.charCodeAt(0));return{key:n,value:decoder.decode(i)}}function parseCeiling(e){let t=/^i([01])o([01])$/u.exec(e);return t===null?void 0:{recordInputs:t[1]===`1`,recordOutputs:t[2]===`1`}}function trimOws(e){return e.replace(/^[\t ]+|[\t ]+$/gu,``)}function baggageKey(e){let t=e.split(`;`,1)[0],n=t.indexOf(`=`);return(n<0?t:t.slice(0,n)).trim()}export{readBaggageMember,readForwardedAudienceBaggage,readForwardedParentSessionBaggage,replaceBaggageMember,writeForwardedAudienceBaggage,writeForwardedParentSessionBaggage};
|
|
@@ -8,3 +8,16 @@ export interface TraceparentContext {
|
|
|
8
8
|
export declare function formatTraceparent(context: TraceparentContext | undefined): string | undefined;
|
|
9
9
|
/** Parses a W3C version-00 traceparent without rejecting the containing request. */
|
|
10
10
|
export declare function parseTraceparent(value: string | null): TraceparentContext | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Restores the eve caller span preserved in W3C `tracestate`.
|
|
13
|
+
*
|
|
14
|
+
* `traceparent` remains the immediate HTTP parent, so its trace identity and
|
|
15
|
+
* flags stay authoritative while eve's vendor entry supplies the earlier
|
|
16
|
+
* semantic caller span ID.
|
|
17
|
+
*/
|
|
18
|
+
export declare function readAgentDispatchTraceContext(value: string | null, transport: TraceparentContext | undefined): TraceparentContext | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Writes eve's prior-parent vendor entry while preserving other valid
|
|
21
|
+
* `tracestate` members and W3C size limits.
|
|
22
|
+
*/
|
|
23
|
+
export declare function writeAgentDispatchTracestate(value: string | undefined, context: TraceparentContext | undefined): string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const TRACEPARENT_PATTERN=/^00-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/iu;function formatTraceparent(e){if(!(e===void 0||!validId(e.traceId,32)||!validId(e.spanId,16)||!Number.isInteger(e.traceFlags)||e.traceFlags<0||e.traceFlags>255))return`00-${e.traceId.toLowerCase()}-${e.spanId.toLowerCase()}-${e.traceFlags.toString(16).padStart(2,`0`)}`}function parseTraceparent(e){if(e===null)return;let t=TRACEPARENT_PATTERN.exec(e.trim());if(t===null)return;let n=t[1].toLowerCase(),r=t[2].toLowerCase();if(validId(n,32)&&validId(r,16))return{isRemote:!0,spanId:r,traceFlags:Number.parseInt(t[3],16),traceId:n}}function validId(e,t){return e.length===t&&/^[0-9a-f]+$/iu.test(e)&&!/^0+$/u.test(e)}export{formatTraceparent,parseTraceparent};
|
|
1
|
+
import{createTraceState}from"#compiled/@opentelemetry/api/index.js";const TRACEPARENT_PATTERN=/^00-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/iu,EVE_DISPATCH_PARENT_PATTERN=/^([0-9a-f]{16})$/u;function formatTraceparent(e){if(!(e===void 0||!validId(e.traceId,32)||!validId(e.spanId,16)||!Number.isInteger(e.traceFlags)||e.traceFlags<0||e.traceFlags>255))return`00-${e.traceId.toLowerCase()}-${e.spanId.toLowerCase()}-${e.traceFlags.toString(16).padStart(2,`0`)}`}function parseTraceparent(e){if(e===null)return;let t=TRACEPARENT_PATTERN.exec(e.trim());if(t===null)return;let n=t[1].toLowerCase(),r=t[2].toLowerCase();if(validId(n,32)&&validId(r,16))return{isRemote:!0,spanId:r,traceFlags:Number.parseInt(t[3],16),traceId:n}}function readAgentDispatchTraceContext(e,t){if(e===null||t===void 0)return;let n=createTraceState(e).get(`eve`),r=(n===void 0?null:EVE_DISPATCH_PARENT_PATTERN.exec(n))?.[1];return r===void 0||!validId(r,16)?void 0:{...t,spanId:r}}function writeAgentDispatchTracestate(e,t){let n=createTraceState(e);return t===void 0||formatTraceparent(t)===void 0?boundedTracestate(n.unset(`eve`)):boundedTracestate(n.set(`eve`,t.spanId.toLowerCase()))}function boundedTracestate(e){let t=e,n=t.serialize(),r=n.split(`,`).filter(Boolean);for(;r.length>32||n.length>512;){let e=r.at(-1);if(e===void 0)return;t=t.unset(e.slice(0,e.indexOf(`=`))),n=t.serialize(),r=n.split(`,`).filter(Boolean)}return n||void 0}function validId(e,t){return e.length===t&&/^[0-9a-f]+$/iu.test(e)&&!/^0+$/u.test(e)}export{formatTraceparent,parseTraceparent,readAgentDispatchTraceContext,writeAgentDispatchTracestate};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { StandardJSONSchemaV1 } from "#compiled/@standard-schema/spec/index.js";
|
|
2
|
+
import type { HeadersValue } from "#client/types.js";
|
|
3
|
+
import { type OutboundAuthFn } from "#public/agents/auth.js";
|
|
4
|
+
import { type RemoteAgentDefinition, type RemoteAgentUrl } from "#public/definitions/remote-agent.js";
|
|
5
|
+
import type { JsonObject } from "#shared/json.js";
|
|
6
|
+
/** Runtime transport for one workspace peer. */
|
|
7
|
+
export interface WorkspaceAgentTransport {
|
|
8
|
+
readonly auth?: OutboundAuthFn;
|
|
9
|
+
readonly headers?: HeadersValue;
|
|
10
|
+
readonly url: RemoteAgentUrl;
|
|
11
|
+
}
|
|
12
|
+
/** A workspace peer exposed as one remote subagent. */
|
|
13
|
+
export interface WorkspaceAgentDefinition {
|
|
14
|
+
/** Overrides the peer agent's description in the parent's tool definition. */
|
|
15
|
+
readonly description?: string;
|
|
16
|
+
readonly forwardPrincipal?: boolean;
|
|
17
|
+
readonly outputSchema?: StandardJSONSchemaV1<unknown, unknown> | JsonObject;
|
|
18
|
+
/** Name of the peer workspace member, such as `research`. */
|
|
19
|
+
readonly name: string;
|
|
20
|
+
/** Overrides environment-aware workspace routing and service authentication. */
|
|
21
|
+
readonly transport?: WorkspaceAgentTransport;
|
|
22
|
+
}
|
|
23
|
+
/** Defines one workspace peer as a remote subagent. */
|
|
24
|
+
export declare function defineWorkspaceAgent(definition: WorkspaceAgentDefinition): RemoteAgentDefinition;
|
|
25
|
+
export declare function workspaceSubagentName(value: unknown): string | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{vercelOidc}from"#public/agents/auth.js";import{defineRemoteAgent}from"#public/definitions/remote-agent.js";const WORKSPACE_AGENT_NAME=Symbol.for(`eve.workspace-agent.name`);function defineWorkspaceAgent(e){let t=e.transport??defaultWorkspaceAgentTransport(e.name),n=defineRemoteAgent({auth:t.auth,description:e.description??``,forwardPrincipal:e.forwardPrincipal,headers:t.headers,outputSchema:e.outputSchema,url:t.url});return Object.defineProperty(n,WORKSPACE_AGENT_NAME,{value:e.name}),n}function workspaceSubagentName(e){return isBrandedWorkspaceSubagent(e)?e[WORKSPACE_AGENT_NAME]:void 0}function isBrandedWorkspaceSubagent(e){return typeof e==`object`&&!!e&&Reflect.has(e,WORKSPACE_AGENT_NAME)}function defaultWorkspaceAgentTransport(e){let t=vercelOidc();return{auth:async()=>(requireVercelWorkspaceEnvironment(),t()),url:()=>{requireVercelWorkspaceEnvironment();let t=process.env.VERCEL_ENV===`production`?process.env.VERCEL_PROJECT_PRODUCTION_URL:process.env.VERCEL_URL;if(t===void 0||t.length===0)throw Error(`The default workspace-agent transport requires VERCEL_URL, or VERCEL_PROJECT_PRODUCTION_URL in production.`);return`https://${t}/${e}`}}}function requireVercelWorkspaceEnvironment(){if(!process.env.VERCEL)throw Error(`No default workspace-agent transport is available in this environment. Provide transport to defineWorkspaceAgent().`)}export{defineWorkspaceAgent,workspaceSubagentName};
|
|
@@ -3,4 +3,5 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export { type AgentCompactionDefinition, type AgentDefinition, type AgentExperimentalDefinition, type AgentLimitsDefinition, type AgentModelDefinition, type AgentModelOptionsDefinition, type AgentReasoningDefinition, type AgentStaticModelDefinition, type AgentWorkflowDefinition, type AgentWorkflowRetentionDefinition, type AgentWorkflowWorldDefinition, type DefinedAgent, type DynamicSubagentDefinition, type DynamicLocalSubagentDefinition, defineAgent, defineDynamic, } from "#public/definitions/agent.js";
|
|
5
5
|
export type { DynamicResolveContext, DynamicSentinel } from "#dynamic/definition.js";
|
|
6
|
+
export { defineWorkspaceAgent, type WorkspaceAgentDefinition, type WorkspaceAgentTransport, } from "#public/definitions/workspace-agent.js";
|
|
6
7
|
export { type RemoteAgentDefinition, type RemoteAgentDefinitionInput, type RemoteAgentUrl, defineRemoteAgent, } from "#public/definitions/remote-agent.js";
|
package/dist/src/public/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineAgent,defineDynamic}from"#public/definitions/agent.js";import{defineRemoteAgent}from"#public/definitions/remote-agent.js";export{defineAgent,defineDynamic,defineRemoteAgent};
|
|
1
|
+
import{defineAgent,defineDynamic}from"#public/definitions/agent.js";import{defineWorkspaceAgent}from"#public/definitions/workspace-agent.js";import{defineRemoteAgent}from"#public/definitions/remote-agent.js";export{defineAgent,defineDynamic,defineRemoteAgent,defineWorkspaceAgent};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type ChildProcessWithoutNullStreams } from "node:child_process";
|
|
2
|
+
import { type ChatGptToken, type ChatGptTokenResolutionInput } from "./token.js";
|
|
3
|
+
export interface CodexAuthStatus {
|
|
4
|
+
readonly authMethod?: string;
|
|
5
|
+
readonly authToken?: string;
|
|
6
|
+
readonly requiresOpenaiAuth?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface CodexAppServer {
|
|
9
|
+
resolveToken(input: ChatGptTokenResolutionInput): Promise<ChatGptToken>;
|
|
10
|
+
restart?(): void;
|
|
11
|
+
}
|
|
12
|
+
export interface CodexAppServerProcess {
|
|
13
|
+
readonly stderr: ChildProcessWithoutNullStreams["stderr"];
|
|
14
|
+
readonly stdin: ChildProcessWithoutNullStreams["stdin"];
|
|
15
|
+
readonly stdout: ChildProcessWithoutNullStreams["stdout"];
|
|
16
|
+
kill(): boolean;
|
|
17
|
+
once(event: "error", listener: (error: Error) => void): this;
|
|
18
|
+
once(event: "exit", listener: (code: number | null, signal: NodeJS.Signals | null) => void): this;
|
|
19
|
+
unref(): void;
|
|
20
|
+
}
|
|
21
|
+
type SpawnCodexAppServer = (command: string, args: readonly string[], options: {
|
|
22
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
23
|
+
stdio: ["pipe", "pipe", "pipe"];
|
|
24
|
+
}) => CodexAppServerProcess;
|
|
25
|
+
export interface CodexAppServerOptions {
|
|
26
|
+
readonly command?: string;
|
|
27
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
28
|
+
readonly spawnProcess?: SpawnCodexAppServer;
|
|
29
|
+
}
|
|
30
|
+
/** Raised only when the `codex` executable cannot be found. */
|
|
31
|
+
export declare class CodexBinaryNotFoundError extends Error {
|
|
32
|
+
constructor(cause?: unknown);
|
|
33
|
+
}
|
|
34
|
+
/** Minimal authenticated subset of Codex's JSONL app-server protocol. */
|
|
35
|
+
export declare class CodexAppServerClient implements CodexAppServer {
|
|
36
|
+
#private;
|
|
37
|
+
constructor(options?: CodexAppServerOptions);
|
|
38
|
+
resolveToken(input: ChatGptTokenResolutionInput): Promise<ChatGptToken>;
|
|
39
|
+
restart(): void;
|
|
40
|
+
}
|
|
41
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{extractCodexAccountIdFromToken,extractCodexAccountLabelFromToken,readCodexJwtExpirationMs}from"./auth.js";import{ChatGptSignInRequiredError}from"./oauth.js";import{ChatGptSignedOutError,isChatGptTokenFresh}from"./token.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{spawn}from"node:child_process";import{isErrnoCode,isObject}from"#shared/guards.js";import{createInterface}from"node:readline";var CodexBinaryNotFoundError=class extends Error{constructor(e){super("The `codex` CLI was not found.",{cause:e}),this.name=`CodexBinaryNotFoundError`}},CodexAppServerClient=class{#e;#t;#n;#r;constructor(e={}){this.#e=e.command??`codex`,this.#t=e.env,this.#n=e.spawnProcess??spawnCodexAppServer}async resolveToken(e){let t=await this.#i(e.forceRefresh);if(t.authMethod!==`chatgpt`||t.authToken===void 0)throw e.forceRefresh?new ChatGptSignInRequiredError:new ChatGptSignedOutError("ChatGPT subscription is not signed in to Codex. Run `codex login` or sign in from /model.");let n=tokenFromCodex(t.authToken);if(!e.forceRefresh&&!isChatGptTokenFresh(n,e.now())){if(t=await this.#i(!0),t.authMethod!==`chatgpt`||t.authToken===void 0)throw new ChatGptSignInRequiredError;n=tokenFromCodex(t.authToken)}return n}async#i(e){let t=await this.#a();try{return await t.getAuthStatus({refreshToken:e})}catch(e){throw t.exited&&(this.#r=void 0),e}}restart(){let e=this.#r;this.#r=void 0,e?.then(e=>e.close()).catch(()=>void 0)}#a(){return this.#r===void 0&&(this.#r=CodexAppServerConnection.start({command:this.#e,env:this.#t,spawnProcess:this.#n}).catch(e=>{throw this.#r=void 0,e})),this.#r}},CodexAppServerConnection=class CodexAppServerConnection{#e;#t;#n=new Map;#r=1;#i=!1;#a;constructor(e){this.#e=e,e.unref(),unrefStream(e.stdin),unrefStream(e.stdout),unrefStream(e.stderr),e.stderr.resume(),this.#t=createInterface({input:e.stdout}),this.#t.on(`line`,e=>this.#l(e)),e.once(`error`,e=>this.#u(e)),e.once(`exit`,(e,t)=>{let n=t===null?`code ${e??`unknown`}`:`signal ${t}`;this.#u(Error(`Codex app-server exited with ${n}.`))})}get exited(){return this.#i}close(){this.#e.kill(),this.#u(Error(`Codex app-server connection was restarted.`))}static async start(e){let t;try{t=e.spawnProcess(e.command,[`app-server`,`--stdio`],{env:e.env,stdio:[`pipe`,`pipe`,`pipe`]})}catch(e){throw appServerError(e)}let n=new CodexAppServerConnection(t);try{return await n.#o(`initialize`,{capabilities:null,clientInfo:{name:`eve`,title:`eve`,version:resolveInstalledPackageInfo().version}}),n.#s(`initialized`,{}),n}catch(e){throw t.kill(),e}}async getAuthStatus(e){let t=await this.#o(`getAuthStatus`,{includeToken:!0,refreshToken:e.refreshToken});if(!isObject(t))throw Error(`Codex app-server returned an invalid authentication response.`);return{...typeof t.authMethod==`string`&&{authMethod:t.authMethod},...typeof t.authToken==`string`&&{authToken:t.authToken},...typeof t.requiresOpenaiAuth==`boolean`&&{requiresOpenaiAuth:t.requiresOpenaiAuth}}}#o(e,t){if(this.#i)return Promise.reject(this.#a??Error(`Codex app-server is not running.`));let n=this.#r++,r=new Promise((e,t)=>{this.#n.set(n,{reject:t,resolve:e})});return this.#c({id:n,method:e,params:t}),r}#s(e,t){this.#c({method:e,params:t})}#c(e){this.#e.stdin.write(`${JSON.stringify(e)}\n`)}#l(e){let t;try{t=JSON.parse(e)}catch{return}if(typeof t.id!=`number`)return;let n=this.#n.get(t.id);if(n!==void 0){if(this.#n.delete(t.id),t.error!==void 0){n.reject(Error(t.error.message??`Codex app-server request failed (${t.error.code}).`));return}n.resolve(t.result)}}#u(e){if(!this.#i){this.#i=!0,this.#a=appServerError(e),this.#t.close();for(let e of this.#n.values())e.reject(this.#a);this.#n.clear()}}};function spawnCodexAppServer(e,t,n){return spawn(e,[...t],n)}function unrefStream(e){`unref`in e&&typeof e.unref==`function`&&e.unref()}function tokenFromCodex(e){let t=extractCodexAccountIdFromToken(e),n=extractCodexAccountLabelFromToken(e),r=readCodexJwtExpirationMs(e);return{token:e,...t!==void 0&&{accountId:t},...n!==void 0&&{accountLabel:n},...r!==void 0&&{expiresAt:r}}}function appServerError(e){if(isErrnoCode(e,`ENOENT`))return new CodexBinaryNotFoundError(e);let t=e instanceof Error?e.message:String(e);return Error(`Codex app-server is unavailable: ${t}`,{cause:e})}export{CodexAppServerClient,CodexBinaryNotFoundError};
|
|
@@ -1,6 +1,28 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ChatGptCredentials, type ChatGptRefreshCredentials } from "./oauth.js";
|
|
2
|
+
import { type ChatGptToken, type ChatGptTokenResolutionInput } from "./token.js";
|
|
3
|
+
export declare class ChatGptInvalidStoredSessionError extends Error {
|
|
4
|
+
constructor();
|
|
5
|
+
}
|
|
2
6
|
export interface ChatGptCredentialStore {
|
|
3
|
-
read(): Promise<ChatGptCredentials | undefined>;
|
|
4
|
-
|
|
7
|
+
read(): Promise<ChatGptRefreshCredentials | ChatGptCredentials | undefined>;
|
|
8
|
+
resolveToken(input: ChatGptTokenResolutionInput & {
|
|
9
|
+
readonly fetch?: typeof fetch;
|
|
10
|
+
}): Promise<ChatGptToken>;
|
|
11
|
+
update(callback: (current: ChatGptRefreshCredentials | ChatGptCredentials | undefined) => Promise<ChatGptCredentials>, options?: {
|
|
12
|
+
replace?: boolean;
|
|
13
|
+
}): Promise<ChatGptCredentials>;
|
|
14
|
+
}
|
|
15
|
+
interface SecretStore {
|
|
16
|
+
get(input: {
|
|
17
|
+
service: string;
|
|
18
|
+
name: string;
|
|
19
|
+
}): Promise<string | null>;
|
|
20
|
+
set(input: {
|
|
21
|
+
service: string;
|
|
22
|
+
name: string;
|
|
23
|
+
value: string;
|
|
24
|
+
}): Promise<void>;
|
|
5
25
|
}
|
|
6
|
-
export declare function createChatGptCredentialStore(path?: string): ChatGptCredentialStore;
|
|
26
|
+
export declare function createChatGptCredentialStore(path?: string, secretStore?: SecretStore): ChatGptCredentialStore;
|
|
27
|
+
export declare function getDefaultChatGptCredentialStore(): ChatGptCredentialStore;
|
|
28
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{randomUUID}from"node:crypto";import{mkdir,
|
|
1
|
+
import{CHATGPT_LOGIN_HINT,ChatGptSignInRequiredError,requestChatGptTokens}from"./oauth.js";import{ChatGptSignedOutError,isChatGptTokenFresh}from"./token.js";import{randomUUID}from"node:crypto";import{mkdir,rm,stat}from"node:fs/promises";import{dirname,join}from"node:path";import{isErrnoCode,isObject}from"#shared/guards.js";import{homedir}from"node:os";import{setTimeout}from"node:timers/promises";import{secrets}from"#compiled/just-secrets/index.js";const SECRET_ID={service:`eve`,name:`chatgpt`},MAX_SECRET_BYTES=2560;var ChatGptInvalidStoredSessionError=class extends Error{constructor(){super(`The ChatGPT session in the OS secret store is invalid. Sign in again from /model to replace it.`)}};function createChatGptCredentialStore(e=join(homedir(),`.eve`,`auth`,`chatgpt.json`),t=secrets){let n;async function removeLegacyFile(){try{await rm(e,{force:!0})}catch{throw Error(`ChatGPT credentials are stored securely, but the old plaintext session could not be removed. Stop older eve processes, remove ~/.eve/auth/chatgpt.json, and retry.`)}}async function load(){let e;try{e=await t.get(SECRET_ID)}catch{throw secretStoreError()}if(e===null){n=void 0;return}let r;try{if(Buffer.byteLength(e)>MAX_SECRET_BYTES)throw Error();r=JSON.parse(e)}catch{throw new ChatGptInvalidStoredSessionError}if(!isObject(r)||typeof r.sessionId!=`string`||!r.sessionId||typeof r.refreshToken!=`string`||!r.refreshToken)throw new ChatGptInvalidStoredSessionError;let i={refreshToken:r.refreshToken,...typeof r.accountId==`string`&&{accountId:r.accountId},...typeof r.accountLabel==`string`&&{accountLabel:r.accountLabel}},a=n?.sessionId===r.sessionId?{...i,accessToken:n.credentials.accessToken,expiresAt:n.credentials.expiresAt}:i;return await removeLegacyFile(),{sessionId:r.sessionId,credentials:a}}let r={async read(){return(await load())?.credentials},async resolveToken(e){let t=await r.read();if(!t)throw e.forceRefresh?new ChatGptSignInRequiredError:new ChatGptSignedOutError(`ChatGPT subscription is not signed in. ${CHATGPT_LOGIN_HINT}`);let n=tokenFromCredentials(t)?.token;(e.forceRefresh||!isChatGptTokenFresh(tokenFromCredentials(t),e.now()))&&(t=await r.update(async t=>{if(!t)throw new ChatGptSignInRequiredError;return`accessToken`in t&&isChatGptTokenFresh(tokenFromCredentials(t),e.now())&&(!e.forceRefresh||t.accessToken!==n)?t:requestChatGptTokens({grant_type:`refresh_token`,refresh_token:t.refreshToken},{fetch:e.fetch,previous:t,now:e.now})}));let i=tokenFromCredentials(t);if(!i)throw Error(`ChatGPT access token is unavailable. ${CHATGPT_LOGIN_HINT}`);return i},async update(r,i){await mkdir(dirname(e),{recursive:!0,mode:448});let a=`${e}.lock`,o=Date.now()+35e3;for(;;)try{await mkdir(a,{mode:448});break}catch(e){if(!isErrnoCode(e,`EEXIST`))throw e;let t=await stat(a).catch(e=>{if(!isErrnoCode(e,`ENOENT`))throw e});if(t&&Date.now()-t.mtimeMs>6e5){await rm(a,{recursive:!0,force:!0});continue}if(Date.now()>=o)throw Error(`Another eve process is updating the ChatGPT session. Retry shortly.`);await setTimeout(100)}try{let e=i?.replace?void 0:await load(),a=await r(e?.credentials),o=e?.sessionId??randomUUID(),s=JSON.stringify({sessionId:o,refreshToken:a.refreshToken,...a.accountId&&{accountId:a.accountId},...a.accountLabel&&{accountLabel:a.accountLabel}});if(Buffer.byteLength(s)>MAX_SECRET_BYTES)throw Error(`The ChatGPT refresh session exceeds the OS secret store's 2,560-byte limit. Use an API-key model instead.`);try{await t.set({...SECRET_ID,value:s})}catch{throw secretStoreError()}return n={sessionId:o,credentials:a},await removeLegacyFile(),a}finally{await rm(a,{recursive:!0,force:!0})}}};return r}let defaultStore;function getDefaultChatGptCredentialStore(){return defaultStore??=createChatGptCredentialStore()}function tokenFromCredentials(e){if(`accessToken`in e)return{token:e.accessToken,expiresAt:e.expiresAt,...e.accountId&&{accountId:e.accountId},...e.accountLabel&&{accountLabel:e.accountLabel}}}function secretStoreError(){let e=process.platform===`linux`?`Install libsecret-tools and start or unlock a Secret Service keyring with a session D-Bus. Headless sessions may need an API-key model.`:process.platform===`win32`?`Allow Windows PowerShell and Credential Manager access in your user session.`:`Unlock your login keychain and allow credential access.`;return Error(`Could not access ChatGPT credentials in the OS secret store. ${e} Retry from /model.`)}export{ChatGptInvalidStoredSessionError,createChatGptCredentialStore,getDefaultChatGptCredentialStore};
|
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
export declare const CHATGPT_ISSUER = "https://auth.openai.com";
|
|
2
2
|
export declare const CHATGPT_CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
|
|
3
3
|
export declare const CHATGPT_LOGIN_HINT = "Open `/model` in `eve dev` and select ChatGPT subscription to sign in.";
|
|
4
|
-
export interface
|
|
5
|
-
readonly accessToken: string;
|
|
4
|
+
export interface ChatGptRefreshCredentials {
|
|
6
5
|
readonly refreshToken: string;
|
|
7
|
-
readonly expiresAt: number;
|
|
8
6
|
readonly accountId?: string;
|
|
9
7
|
readonly accountLabel?: string;
|
|
10
8
|
}
|
|
9
|
+
export interface ChatGptCredentials extends ChatGptRefreshCredentials {
|
|
10
|
+
readonly accessToken: string;
|
|
11
|
+
readonly expiresAt: number;
|
|
12
|
+
}
|
|
11
13
|
export declare class ChatGptSignInRequiredError extends Error {
|
|
12
14
|
constructor();
|
|
13
15
|
}
|
|
14
16
|
export declare function requestChatGptTokens(parameters: Record<string, string>, options?: {
|
|
15
17
|
fetch?: typeof fetch;
|
|
16
18
|
signal?: AbortSignal;
|
|
17
|
-
previous?:
|
|
19
|
+
previous?: ChatGptRefreshCredentials;
|
|
18
20
|
now?: () => number;
|
|
19
21
|
}): Promise<ChatGptCredentials>;
|
|
20
22
|
export declare function readChatGptAuthResponse(response: Response): Promise<unknown>;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { type ChatGptCredentialStore } from "./credential-store.js";
|
|
2
|
+
import { type CodexAppServer, type CodexAppServerOptions } from "./codex-app-server.js";
|
|
3
|
+
import { type ChatGptToken } from "./token.js";
|
|
2
4
|
export type ChatGptAuthState = {
|
|
3
5
|
readonly kind: "checking";
|
|
4
6
|
} | {
|
|
@@ -12,20 +14,18 @@ export type ChatGptAuthState = {
|
|
|
12
14
|
readonly kind: "unavailable";
|
|
13
15
|
readonly reason: string;
|
|
14
16
|
};
|
|
15
|
-
export
|
|
16
|
-
readonly accountId?: string;
|
|
17
|
-
readonly accountLabel?: string;
|
|
18
|
-
readonly expiresAt?: number;
|
|
19
|
-
readonly token: string;
|
|
20
|
-
}
|
|
17
|
+
export type { ChatGptToken } from "./token.js";
|
|
21
18
|
export interface CodexTokenBroker {
|
|
19
|
+
credentialOwner(): ChatGptCredentialOwner | undefined;
|
|
22
20
|
getToken(input: {
|
|
23
21
|
readonly reason: "rejected" | "request";
|
|
24
22
|
}): Promise<ChatGptToken>;
|
|
25
23
|
refreshState(): Promise<ChatGptAuthState>;
|
|
26
24
|
state(): ChatGptAuthState;
|
|
27
25
|
}
|
|
28
|
-
export
|
|
26
|
+
export type ChatGptCredentialOwner = "codex" | "eve";
|
|
27
|
+
export interface CodexTokenBrokerOptions extends CodexAppServerOptions {
|
|
28
|
+
readonly appServer?: CodexAppServer;
|
|
29
29
|
readonly store?: ChatGptCredentialStore;
|
|
30
30
|
readonly fetch?: typeof fetch;
|
|
31
31
|
readonly now?: () => number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{ChatGptSignInRequiredError}from"./oauth.js";import{ChatGptSignedOutError,isChatGptTokenFresh}from"./token.js";import{CodexAppServerClient,CodexBinaryNotFoundError}from"./codex-app-server.js";import{getDefaultChatGptCredentialStore}from"./credential-store.js";function createCodexTokenBroker(e={}){let t=e.appServer??new CodexAppServerClient(e),n=e.store??getDefaultChatGptCredentialStore(),r=e.now??Date.now,i,a={kind:`checking`},o,s,c;return{credentialOwner(){return i},getToken(e){return getToken(e.reason)},refreshState(){if(c!==void 0)return c;let e=refreshAuthState();return c=e,e.finally(()=>{c===e&&(c=void 0)}),e},state(){return a}};async function refreshAuthState(){s!==void 0&&await s.promise.catch(()=>void 0),i===`codex`&&(a.kind===`signed-out`||a.kind===`reauth-required`)?t.restart?.():i===`eve`&&(i=void 0),o=void 0;try{await getToken(`request`)}catch{}return a}function getToken(e){let t=e===`rejected`;if(!t&&o!==void 0&&isChatGptTokenFresh(o,r()))return Promise.resolve(o);if(s!==void 0&&(!t||s.forced))return s.promise;let n=s?.promise,i=(n===void 0?resolveToken(t):n.catch(()=>void 0).then(()=>resolveToken(t))).finally(()=>{s?.promise===i&&(s=void 0)});return s={forced:t,promise:i},i}async function resolveToken(s){try{let c;if(i===`eve`)c=await n.resolveToken({forceRefresh:s,fetch:e.fetch,now:r});else try{c=await t.resolveToken({forceRefresh:s,now:r}),i=`codex`}catch(t){if(!(t instanceof CodexBinaryNotFoundError))throw i??=`codex`,t;i=`eve`,c=await n.resolveToken({forceRefresh:s,fetch:e.fetch,now:r})}return o=c,a=readyState(c),c}catch(e){throw o=void 0,a=e instanceof ChatGptSignInRequiredError?{kind:`reauth-required`}:e instanceof ChatGptSignedOutError?{kind:`signed-out`}:{kind:`unavailable`,reason:e instanceof Error?e.message:String(e)},e}}}let defaultBroker;function getDefaultCodexTokenBroker(){return defaultBroker??=createCodexTokenBroker(),defaultBroker}function readyState(e){return{kind:`ready`,...e.accountLabel!==void 0&&{accountLabel:e.accountLabel}}}export{createCodexTokenBroker,getDefaultCodexTokenBroker};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface ChatGptToken {
|
|
2
|
+
readonly accountId?: string;
|
|
3
|
+
readonly accountLabel?: string;
|
|
4
|
+
readonly expiresAt?: number;
|
|
5
|
+
readonly token: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ChatGptTokenResolutionInput {
|
|
8
|
+
readonly forceRefresh: boolean;
|
|
9
|
+
readonly now: () => number;
|
|
10
|
+
}
|
|
11
|
+
export declare class ChatGptSignedOutError extends Error {
|
|
12
|
+
}
|
|
13
|
+
export declare function isChatGptTokenFresh(token: ChatGptToken | undefined, now: number): boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var ChatGptSignedOutError=class extends Error{};function isChatGptTokenFresh(e,t){return e!==void 0&&(e.expiresAt===void 0||e.expiresAt-3e5>t)}export{ChatGptSignedOutError,isChatGptTokenFresh};
|
|
@@ -7,7 +7,8 @@ export interface CodexTransportOptions {
|
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
9
|
* Routes OpenAI Responses requests through the Codex backend. Authentication is
|
|
10
|
-
* resolved
|
|
10
|
+
* resolved through Codex app-server when available, with eve-owned credentials
|
|
11
|
+
* used only when the Codex binary is not installed.
|
|
11
12
|
*/
|
|
12
13
|
export declare function createCodexFetch(options?: CodexTransportOptions): Fetch;
|
|
13
14
|
export declare function rewriteCodexEndpoint(input: string, codexApiEndpoint?: string): string;
|
|
@@ -8,8 +8,9 @@ import type { LanguageModel } from "ai";
|
|
|
8
8
|
* only, so any other provider-qualified id is rejected. Model availability is
|
|
9
9
|
* enforced by the Codex backend per account at call time, not at compile time.
|
|
10
10
|
*
|
|
11
|
-
* eve
|
|
12
|
-
*
|
|
11
|
+
* eve uses Codex app-server when the Codex CLI is installed. If the binary is
|
|
12
|
+
* not found, eve stores and refreshes its own local credentials instead. This
|
|
13
|
+
* model works in local dev and fails in a deployment.
|
|
13
14
|
* Branch on environment for production:
|
|
14
15
|
*
|
|
15
16
|
* ```ts
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/** A route accepted by eve's Vercel configuration composer. */
|
|
2
|
+
export interface EveVercelRouteConfig {
|
|
3
|
+
readonly destination?: string | {
|
|
4
|
+
readonly service?: string;
|
|
5
|
+
readonly type?: string;
|
|
6
|
+
};
|
|
7
|
+
readonly handle?: string;
|
|
8
|
+
readonly src?: string;
|
|
9
|
+
readonly transforms?: readonly Record<string, unknown>[];
|
|
10
|
+
readonly [key: string]: unknown;
|
|
11
|
+
}
|
|
12
|
+
/** A service accepted by eve's Vercel configuration composer. */
|
|
13
|
+
export interface EveVercelServiceConfig {
|
|
14
|
+
readonly buildCommand?: string;
|
|
15
|
+
readonly entrypoint?: string;
|
|
16
|
+
readonly framework?: string;
|
|
17
|
+
readonly mount?: string | {
|
|
18
|
+
readonly path?: string;
|
|
19
|
+
readonly subdomain?: string;
|
|
20
|
+
};
|
|
21
|
+
readonly routes?: readonly EveVercelRouteConfig[];
|
|
22
|
+
readonly root?: string;
|
|
23
|
+
readonly type?: string;
|
|
24
|
+
readonly [key: string]: unknown;
|
|
25
|
+
}
|
|
26
|
+
/** The portion of a programmatic Vercel configuration composed by eve. */
|
|
27
|
+
export interface EveVercelConfig {
|
|
28
|
+
readonly experimentalServices?: unknown;
|
|
29
|
+
readonly experimentalServicesV2?: unknown;
|
|
30
|
+
readonly routes?: readonly EveVercelRouteConfig[];
|
|
31
|
+
readonly services?: Readonly<Record<string, EveVercelServiceConfig>> | readonly (EveVercelServiceConfig & {
|
|
32
|
+
readonly name: string;
|
|
33
|
+
})[];
|
|
34
|
+
readonly [key: string]: unknown;
|
|
35
|
+
}
|
|
36
|
+
/** Options for composing an eve workspace into a programmatic Vercel configuration. */
|
|
37
|
+
export interface WithEveOptions {
|
|
38
|
+
/** Eve workspace root. Defaults to the directory evaluating `vercel.ts`. */
|
|
39
|
+
readonly root?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Add a hostless eve workspace's generated agent services and transport routes to `vercel.ts`.
|
|
43
|
+
*
|
|
44
|
+
* The returned object is a plain Vercel configuration. Vercel resolves it before independently
|
|
45
|
+
* building the authored services and each generated eve agent service.
|
|
46
|
+
*/
|
|
47
|
+
export declare function withEve<TConfig extends EveVercelConfig>(config: TConfig, options?: WithEveOptions): Promise<Omit<TConfig, "routes" | "services"> & {
|
|
48
|
+
readonly routes: readonly EveVercelRouteConfig[];
|
|
49
|
+
readonly services: Readonly<Record<string, EveVercelServiceConfig>>;
|
|
50
|
+
}>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{mkdir}from"node:fs/promises";import{join,resolve}from"node:path";import{resolveEveProjectContext}from"#internal/project-context.js";import{createServiceConfigRecord}from"#internal/vercel/vercel-services-config.js";import{createEveServiceName,createEveServiceRouteSrc}from"#internal/vercel/eve-service-contribution.js";import{assembleEveVercelServices}from"#internal/vercel/assemble-eve-services.js";import{quoteVercelShellArgument,toVercelRelativePath}from"#internal/vercel/build-command.js";import{resolveEveBinaryPath}from"#shared/resolve-eve-binary.js";function toInternalConfig(e){return e}function assertComposableConfig(e,t){if(e.experimentalServices!==void 0||e.experimentalServicesV2!==void 0)throw Error(`withEve cannot compose experimentalServices or experimentalServicesV2. Remove the obsolete field and define authored services under services.`);let n=toInternalConfig(e),r=createServiceConfigRecord(n.services);for(let n of t){let t=createEveServiceName(n);if(Object.hasOwn(r,t))throw Error(`Vercel service key ${JSON.stringify(t)} conflicts with the service generated for eve workspace agent ${JSON.stringify(n)}. Remove or rename the authored service; withEve owns this key.`);let i=createEveServiceRouteSrc(`/${n}`);if(e.routes?.some(e=>e.src===i))throw Error(`Vercel route ${JSON.stringify(i)} conflicts with the transport route generated for eve workspace agent ${JSON.stringify(n)}. Remove the authored route; withEve adds it automatically.`)}}async function withEve(e,t={}){let n=resolve(t.root??process.cwd()),r=await resolveEveProjectContext(n);if(r.kind!==`workspace`||r.workspace.root!==n)throw Error(`withEve must run at an eve workspace root; received ${n}.`);let{workspace:i}=r;if(i.members.length===0)throw Error(`withEve found no workspace agents under ${join(n,`agents`)}. Add an agent or remove withEve from vercel.ts.`);let a=i.members.map(e=>e.name),o=new Set(a.map(createEveServiceName));assertComposableConfig(e,a);let s=join(n,`.vercel`,`output`),c=toInternalConfig(e),l=assembleEveVercelServices({agents:i.members.map(e=>({agent:{appRoot:e.appRoot,buildCommand:`node ${quoteVercelShellArgument(toVercelRelativePath(e.appRoot,resolveEveBinaryPath(e.appRoot)))} build`,name:e.name,publicRoutePrefix:`/${e.name}`,workspaceMember:!0},target:{hostOutputDirectory:s,projectRoot:n}})),routes:c.routes,services:createServiceConfigRecord(c.services)});await Promise.all(l.rootDirectories.map(e=>mkdir(e,{recursive:!0})));let u=Object.fromEntries(Object.entries(l.services).map(([e,t])=>{if(!o.has(e))return[e,t];let{routePrefix:n,...r}=t;return[e,r]}));return{...e,routes:l.routes,services:u}}export{withEve};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import{SELF_MODIFICATION_CONFIG_PATH}from"./git-workspace.js";import{createHash}from"node:crypto";import{readFile,writeFile}from"node:fs/promises";import{join,relative}from"node:path";import{discoverAgent}from"#discover/discover-agent.js";import{execFile}from"node:child_process";import{promisify}from"node:util";import{stripLogicalPathExtension}from"#discover/filesystem.js";const runFile=promisify(execFile);function connectorName(e,t){return`selfmod-${e}-${t}`.toLowerCase().replaceAll(/[^a-z0-9-]/gu,`-`)}function renderSelfModificationConfig(e){if(e===void 0)return`import { defineSelfModificationConfig } from "eve/self-modification/config";
|
|
2
2
|
|
|
3
|
-
export default defineSelfModificationConfig({
|
|
3
|
+
export default defineSelfModificationConfig({
|
|
4
|
+
local: { enabled: true },
|
|
5
|
+
});
|
|
4
6
|
`;let t=[...new Set(e.channelNames)].filter(e=>e!==`eve`).sort(),n=(e.vercelBackend?t:[]).map(e=>` case ${JSON.stringify(`channel:${e}`)}:
|
|
5
7
|
// Authorize trusted principals for this channel before returning true.
|
|
6
8
|
return false;`).join(`
|
|
@@ -38,6 +40,9 @@ ${r} default:
|
|
|
38
40
|
},
|
|
39
41
|
},
|
|
40
42
|
});
|
|
41
|
-
`;return`// eve-self-modification: generated-v1 digest:${createHash(`sha256`).update(i).digest(`hex`)}\n${i}`}function classifySelfModificationConfig(e){if(e===void 0)return`missing`;if(e===renderSelfModificationConfig()
|
|
43
|
+
`;return`// eve-self-modification: generated-v1 digest:${createHash(`sha256`).update(i).digest(`hex`)}\n${i}`}function classifySelfModificationConfig(e){if(e===void 0)return`missing`;if(e===renderSelfModificationConfig()||e===`import { defineSelfModificationConfig } from "eve/self-modification/config";
|
|
44
|
+
|
|
45
|
+
export default defineSelfModificationConfig({});
|
|
46
|
+
`)return`local`;let[t,...n]=e.split(`
|
|
42
47
|
`);return/^\/\/ eve-self-modification: generated-v1 digest:([a-f0-9]{64})$/u.exec(t??``)?.[1]===createHash(`sha256`).update(n.join(`
|
|
43
48
|
`)).digest(`hex`)?`generated`:`authored`}function parseGitHubRemote(e){let t=e.trim().match(/^(?:https?:\/\/github\.com\/|git@github\.com:|ssh:\/\/git@github\.com\/)([^/]+)\/([^/]+?)(?:\.git)?$/u);return t?.[1]===void 0||t[2]===void 0?void 0:{owner:t[1],repo:t[2]}}function defaultSelfModificationSetupOperations(e){let t=join(e,SELF_MODIFICATION_CONFIG_PATH);return{async detectChannelNames(){return(await discoverAgent({appRoot:e,agentRoot:join(e,`agent`)})).manifest.channels.map(e=>stripLogicalPathExtension(e.logicalPath).replace(/^channels\//,``))},async detectGitRepository(){let t=await gitOutput(e,[`config`,`--get`,`remote.origin.url`]),n=t===void 0?void 0:parseGitHubRemote(t),r=await gitOutput(e,[`symbolic-ref`,`--quiet`,`--short`,`refs/remotes/origin/HEAD`]),i=await gitOutput(e,[`rev-parse`,`--show-toplevel`]);return{...n,branch:r?.replace(/^origin\//u,``),directory:i===void 0?void 0:repositoryRelativeDirectory(i,e),remoteKind:t===void 0?`missing`:n===void 0?`other`:`github`}},async readConfig(){try{return await readFile(t,`utf8`)}catch(e){if(e.code===`ENOENT`)return;throw e}},writeConfig:e=>writeFile(t,e,`utf8`),async findOrCreateConnector(t){let n=await vercel(e,[`connect`,`list`,`-F`,`json`]);if(!n.ok)throw Error(`Vercel Connect requires an authenticated Vercel CLI linked to this project.`);let r=parseConnectors(n.stdout),i=`github/${t}`,a=r.find(e=>e.uid===i);if(a!==void 0){if(a.type!==`github`)throw Error(`The existing connector ${i} is not a GitHub connector.`);return a.uid}let o=await vercel(e,[`connect`,`create`,`github`,`--name`,t,`-F`,`json`]),s=o.ok?parseCreatedConnector(o.stdout):void 0;if(s===void 0||!s.startsWith(`github/`))throw Error(`Could not create a GitHub Vercel Connect connector.`);return s},async attachConnector(t){let n=await readLinkedProject(e);if(n===void 0)throw Error("Vercel Connect requires this directory to be linked to a Vercel project. Run `vercel link` and retry.");if(!(await vercel(e,[`connect`,`attach`,t,`--project`,n.projectId,`--environment`,`production`,`--yes`])).ok)throw Error(`Could not attach ${t} to the linked Vercel project for Production.`)}}}function parseCreatedConnector(e){try{let t=JSON.parse(e);return typeof t.uid==`string`?t.uid:void 0}catch{return}}function parseConnectors(e){try{let t=JSON.parse(e);return(Array.isArray(t.connectors)?t.connectors:[t]).flatMap(e=>typeof e==`object`&&e&&typeof e.uid==`string`&&typeof e.type==`string`?[{uid:e.uid,type:e.type}]:[])}catch{return[]}}async function vercel(e,t){try{return{ok:!0,stdout:(await runFile(`vercel`,t,{cwd:e})).stdout}}catch{return{ok:!1,stdout:``}}}async function readLinkedProject(e){try{let t=JSON.parse(await readFile(join(e,`.vercel`,`project.json`),`utf8`));return typeof t.projectId==`string`?{projectId:t.projectId}:void 0}catch{return}}function repositoryRelativeDirectory(e,t,n=relative){return n(e,t).replaceAll(`\\`,`/`)||`.`}function repositoryPartError(e){return/^[A-Za-z0-9_.-]+$/u.test(e)?void 0:`Enter a valid GitHub owner or repository name.`}function directoryError(e){return e===`.`||e.length>0&&!e.startsWith(`/`)&&!e.includes(`\\`)&&e.split(`/`).every(e=>e!==``&&e!==`.`&&e!==`..`)?void 0:`Enter a safe repository-relative directory or ".".`}function gitRefError(e){return/^[A-Za-z0-9][A-Za-z0-9._/-]*$/u.test(e)&&!e.endsWith(`.`)&&!e.endsWith(`/`)&&!e.includes(`..`)&&!e.includes(`//`)&&!e.includes(`@{`)?void 0:`Enter a valid branch name.`}async function gitOutput(e,t){try{return(await runFile(`git`,t,{cwd:e})).stdout.trim()||void 0}catch{return}}export{classifySelfModificationConfig,connectorName,defaultSelfModificationSetupOperations,directoryError,gitRefError,parseGitHubRemote,renderSelfModificationConfig,repositoryPartError,repositoryRelativeDirectory};
|
|
@@ -3,12 +3,13 @@ import { type CodexTokenBroker } from "#public/models/openai/chatgpt/token-broke
|
|
|
3
3
|
interface ChatGptAuthOptions {
|
|
4
4
|
readonly signal?: AbortSignal;
|
|
5
5
|
readonly broker?: CodexTokenBroker;
|
|
6
|
+
readonly codexLogin?: (signal?: AbortSignal) => Promise<void>;
|
|
6
7
|
readonly store?: ChatGptCredentialStore;
|
|
7
8
|
readonly fetch?: typeof fetch;
|
|
8
9
|
readonly open?: (url: string) => void;
|
|
9
10
|
readonly log?: (message: string) => void;
|
|
10
11
|
readonly headless?: boolean;
|
|
11
12
|
}
|
|
12
|
-
/** Signs in
|
|
13
|
+
/** Signs in through the credential owner selected by the ChatGPT auth facade. */
|
|
13
14
|
export declare function ensureChatGptAuth(options?: ChatGptAuthOptions): Promise<void>;
|
|
14
15
|
export {};
|