@trayai/helix-sdk 1.13.2 → 1.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/README.md +3 -3
- package/dist/broker/index.js +1 -1
- package/dist/{chunk-3WKD2ENP.js → chunk-GMEVZH35.js} +1 -1
- package/dist/chunk-LKZKDHYO.js +1 -0
- package/dist/{define-agent-DXV_nHvs.d.ts → define-agent-BEUgQ_5-.d.ts} +15 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +3 -3
- package/dist/internal/index.d.ts +9 -6
- package/dist/internal/index.js +1 -1
- package/dist/testing/index.d.ts +18 -3
- package/dist/testing/index.js +1 -1
- package/dist/{types-CVW_-1wh.d.ts → types-BSbvztCi.d.ts} +10 -4
- package/package.json +1 -1
- package/dist/chunk-JKFMPHA4.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,36 @@ project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
8
8
|
The SDK and [`@trayai/helix-cli`](https://www.npmjs.com/package/@trayai/helix-cli) are
|
|
9
9
|
released together and share a version — install matching versions.
|
|
10
10
|
|
|
11
|
+
## 1.14.0
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **`ctx.identity.user.email` and `ctx.identity.user.name`.** `ctx.identity` is now
|
|
16
|
+
`{ user: { id, email, name } }` for requests made by logged-in users and project API
|
|
17
|
+
tokens, and is still `null` when there is no user (schedules, `ctx.callFunctionAsync`
|
|
18
|
+
runs, anonymous callers). `email` and `name` are `null` when the platform has no value
|
|
19
|
+
for them. `helix dev` has no sign-in flow, so `ctx.identity` is `null` locally. In tests,
|
|
20
|
+
pass an `identity` to `runWithContext` to set them.
|
|
21
|
+
- **`MockContext` type** (from `@trayai/helix-sdk/testing`) for typing `runWithContext`
|
|
22
|
+
fixtures; `identity.user.email` and `.name` are optional in it.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- **`TrayContext['identity']` and `PlatformContext['identity']` now require `email` and
|
|
27
|
+
`name`** (each `string | null`). This is a compile-time break for code that builds an
|
|
28
|
+
identity value, shipped in a minor release as a deliberate exception to the 1.0 promise:
|
|
29
|
+
reads are unaffected, nothing changes at runtime, the documented inline `runWithContext`
|
|
30
|
+
pattern still compiles, and the fix is one line. Affected: fixtures typed
|
|
31
|
+
`Partial<PlatformContext>` (the old `runWithContext` parameter type), hand-built
|
|
32
|
+
`TrayContext` or `PlatformContext` literals that set `identity`, handlers that assign
|
|
33
|
+
`ctx.identity = { user: { id } }`, and helpers whose return type is
|
|
34
|
+
`TrayContext['identity']`. Add `email` and `name`, or retype fixtures as `MockContext`.
|
|
35
|
+
`runWithContext` still accepts identity mocks without them, such as
|
|
36
|
+
`runWithContext({ identity: { user: { id } } }, …)`, and defaults both to `null`. Note
|
|
37
|
+
that `helix deploy` type-checks everything your `tsconfig.json` includes (`functions/**`
|
|
38
|
+
by default), so an affected fixture or helper there fails the deploy after upgrading
|
|
39
|
+
until it is updated.
|
|
40
|
+
|
|
11
41
|
## 1.13.2
|
|
12
42
|
|
|
13
43
|
No user-visible changes in this release — co-versioned with `@trayai/helix-cli`'s changes.
|
package/README.md
CHANGED
|
@@ -91,7 +91,7 @@ Every HTTP handler receives a `ctx` (`TrayContext`); scheduled handlers receive
|
|
|
91
91
|
| `ctx.status(code)` | Set the response status |
|
|
92
92
|
| `ctx.error(code, message)` | Throw an HTTP error mapped to that status |
|
|
93
93
|
| `ctx.executionId` / `ctx.deploymentId` / `ctx.traceId` | Invocation identifiers |
|
|
94
|
-
| `ctx.identity` |
|
|
94
|
+
| `ctx.identity` | The caller's identity — `{ user: { id, email, name } }`, or `null` when no user is known. `email` and `name` are `null` when the platform has no value for them |
|
|
95
95
|
| `ctx.request` | The raw underlying request event |
|
|
96
96
|
|
|
97
97
|
## Authenticated HTTP
|
|
@@ -615,14 +615,14 @@ const result = await runWithContext({ input: { name: 'Ada' } }, async () => {
|
|
|
615
615
|
});
|
|
616
616
|
```
|
|
617
617
|
|
|
618
|
-
The mock context is a Proxy: touching an always-present field (`http`, `db`, `log`, `executionId`, …) you didn't provide throws a descriptive error, so tests fail loudly — as does touching a field that isn't part of the context at all. Fields that aren't guaranteed on every execution (for example `userId` and `identity`) instead return `undefined` when unset, just as they can at runtime.
|
|
618
|
+
The mock context is a Proxy: touching an always-present field (`http`, `db`, `log`, `executionId`, …) you didn't provide throws a descriptive error, so tests fail loudly — as does touching a field that isn't part of the context at all. Fields that aren't guaranteed on every execution (for example `userId` and `identity`) instead return `undefined` when unset, just as they can at runtime. To test code that reads the caller's email or name, pass an identity: `runWithContext({ userId: 'u-1', identity: { user: { id: 'u-1', email: 'ada@example.com', name: 'Ada' } } }, …)`. In a mock identity, `email` and `name` may be omitted — they default to `null`, as in a real context. Type your own fixtures with the exported `MockContext`.
|
|
619
619
|
|
|
620
620
|
## Entry points
|
|
621
621
|
|
|
622
622
|
| Import | Contents |
|
|
623
623
|
|--------|----------|
|
|
624
624
|
| `@trayai/helix-sdk` | `defineFunction`, `defineSchedule`, `defineConfig`, `getContext`, `loadConfig`, `requireWorkspaceId`, `createConfigService`, and the public types |
|
|
625
|
-
| `@trayai/helix-sdk/testing` | `runWithContext` |
|
|
625
|
+
| `@trayai/helix-sdk/testing` | `runWithContext`, `MockContext` (type) |
|
|
626
626
|
|
|
627
627
|
Key exported types include `TrayContext`, `ScheduleContext`, `ScheduleTrigger`, `TrayConfig`, `LoadedTrayConfig`, `HttpClient`, `KeyValueStore`, `FileSystemClient`, `Logger`, `ConfigService`, and `WorkspaceIdRequiredError`.
|
|
628
628
|
|
package/dist/broker/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{A as u,B as d,D as p,F as m,G as c,H as k,I as g,J as b,j as l}from"../chunk-
|
|
1
|
+
import{A as u,B as d,D as p,F as m,G as c,H as k,I as g,J as b,j as l}from"../chunk-LKZKDHYO.js";import{z as s}from"zod";function v(e,t){let r=`${l(e).hosts.api}/private/v1/helix/authentications/templates`;return t==="dev"?`${r}/dev`:r}var h=s.object({templates:s.array(s.object({serviceName:s.string(),serviceVersion:s.number().int(),authenticationType:s.string(),strategy:s.string().optional()}))}),S=3e4;async function y(e){let t=new Headers;for(let[n,T]of Object.entries(e.credentialHeaders))t.set(n,T);let r=await fetch(e.templatesUrl,{method:"GET",headers:t,redirect:"manual",signal:AbortSignal.timeout(e.timeoutMs??S)}),a=await r.text(),o=a;try{o=JSON.parse(a)}catch{}if(r.ok){let n=h.safeParse(o);return n.success?{kind:"templates",result:n.data}:{kind:"brokerError",status:r.status,message:"malformed templates-discovery response",body:o}}let i=u.safeParse(o);return i.success?{kind:"brokerError",status:r.status,code:i.data.error.code,message:i.data.error.message,body:o}:{kind:"brokerError",status:r.status,message:a||`templates-discovery request failed with status ${r.status}`,body:o}}async function R(e){let t=p({authenticationId:e.authenticationId,method:e.method,url:e.url,body:e.body,headers:e.headers,query:e.query}),r=await c({proxyUrl:d(e.env,"dev"),credentialHeaders:{Authorization:`Bearer ${e.devToken}`},request:t,timeoutMs:e.timeoutMs??m});return r.kind==="brokerError"?{kind:"brokerError",brokerStatus:r.status,code:r.code,body:r.body}:{kind:"upstream",upstream:r.response}}async function f(e){k(e.url);let t=await b({signUrl:g(e.env,"dev"),credentialHeaders:{Authorization:`Bearer ${e.devToken}`},body:{authenticationId:e.authenticationId,url:e.url,...e.method!==void 0?{method:e.method}:{},...e.expiresIn!==void 0?{expiresIn:e.expiresIn}:{}},timeoutMs:e.timeoutMs});return t.kind==="brokerError"?{kind:"brokerError",brokerStatus:t.status,code:t.code,body:t.body}:{kind:"signed",signed:t.result}}async function x(e){let t=await y({templatesUrl:v(e.env,"dev"),credentialHeaders:{Authorization:`Bearer ${e.devToken}`},timeoutMs:e.timeoutMs});return t.kind==="brokerError"?{kind:"brokerError",brokerStatus:t.status,code:t.code,body:t.body}:{kind:"templates",templates:t.result.templates}}export{R as callBrokerDev,f as callS3SignDev,x as callTemplatesDev};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as mn,b as Ve}from"./chunk-WUCX7RZO.js";import{A as yn,B as fe,C as z,D as ne,E as hn,G as wn,H as Sn,I as bn,J as vn,a as U,b as de,d as E,e as ue,f as $,h as un,j,k as pn,o as fn,r as d,t as Ie,u as ze,v as te,w as Re,x as Ge,y as pe,z as gn}from"./chunk-
|
|
1
|
+
import{a as mn,b as Ve}from"./chunk-WUCX7RZO.js";import{A as yn,B as fe,C as z,D as ne,E as hn,G as wn,H as Sn,I as bn,J as vn,a as U,b as de,d as E,e as ue,f as $,h as un,j,k as pn,o as fn,r as d,t as Ie,u as ze,v as te,w as Re,x as Ge,y as pe,z as gn}from"./chunk-LKZKDHYO.js";var sc="tray-config-bridge",ic="tray-dev-token-bridge",Je=null;function ac(e){Je=e}function A(){if(!Je)throw new Error("Active tray config not seeded. Worker boot must call setActiveConfig() before handlers run.");return Je}function cc(){Je=null}import{AsyncLocalStorage as Bn}from"async_hooks";import{trace as cs,SpanKind as ls,SpanStatusCode as Ze}from"@opentelemetry/api";import{ExportResultCode as ds,W3CTraceContextPropagator as us}from"@opentelemetry/core";import{NodeTracerProvider as ps,SimpleSpanProcessor as fs,BatchSpanProcessor as ms}from"@opentelemetry/sdk-trace-node";import{OTLPTraceExporter as Jo}from"@opentelemetry/exporter-trace-otlp-proto";import{OTLPLogExporter as Wo}from"@opentelemetry/exporter-logs-otlp-proto";function Ct(e){return j(e).hosts.ingest}function Xo(){return $()??""}function xn(){return{[U]:Xo()}}function An(){let e=Ct(A().region);return new Jo({url:`${e}/v1/traces`,headers:()=>Promise.resolve(xn())})}function En(){let e=Ct(A().region);return new Wo({url:`${e}/v1/logs`,headers:()=>Promise.resolve(xn())})}import{logs as Cn,SeverityNumber as We}from"@opentelemetry/api-logs";import{LoggerProvider as Zo,BatchLogRecordProcessor as es}from"@opentelemetry/sdk-logs";function Ce(e){try{return JSON.stringify(e)}catch(t){return JSON.stringify({_serialization_error:t instanceof Error?t.message:String(t)})}}function Yo(e){return new TextEncoder().encode(e).length}var In="\u2026[truncated]",Qo=Yo(In),Te=4096;function re(e,t=Te){let n=new TextEncoder().encode(e);if(n.length<=t)return e;let r=n.subarray(0,t-Qo);return new TextDecoder("utf-8").decode(r).replace(/�$/,"")+In}function k(e,t=Te){return re(Ce(e),t)}var ts="@trayai/helix-sdk",ke,Rn={debug:{number:We.DEBUG,text:"DEBUG"},info:{number:We.INFO,text:"INFO"},warn:{number:We.WARN,text:"WARN"},error:{number:We.ERROR,text:"ERROR"}};function ns(){return E().mode==="lambda"?[new es({exporter:En()})]:[]}function Tn(){if(ke!==void 0)return;let e=ns();e.length!==0&&(ke=new Zo({processors:e}),Cn.setGlobalLoggerProvider(ke))}function rs(e,t,n){let r=Rn[e]??Rn.info;return{severityNumber:r.number,severityText:r.text,body:t,...n?{attributes:{"tray.log.meta":k(n)}}:{}}}function kn(e,t,n){Cn.getLogger(ts).emit(rs(e,t,n))}async function Pn(e=2e3){if(ke===void 0)return;let t;try{await Promise.race([ke.forceFlush(),new Promise(n=>{t=setTimeout(n,e)})])}catch(n){process.stderr.write(`[helix-sdk] otel log flush failed: ${n instanceof Error?n.message:String(n)}
|
|
2
2
|
`)}finally{t!==void 0&&clearTimeout(t)}}function Tt(){let e=process.env.TRAY_PRETTY_LOGS;return e==="1"||e==="true"}function os(){if(process.env.NO_COLOR!==void 0)return!1;let e=process.env.FORCE_COLOR;return e!==void 0&&e!=="0"&&e!=="false"?!0:!!process.stdout.isTTY&&process.env.TERM!=="dumb"}function D(e,t){return os()?`\x1B[${e}m${t}\x1B[0m`:t}var ss=5,is={FN:"1;35",INFO:"34",AUTH:"35",API:"36",AGENT:"1;36",TOOL:"36",WARN:"33",ERROR:"31",DEBUG:"90"},Xe="32",Ye="31",as="33",oe="2",Qe="1";function se(e){return D(is[e]??"0",e.padEnd(ss))}function On(e,t){return`${se("FN")} ${D(Qe,`${e} ${t}`.trim())}`}function _n(e,t,n,r){let o=e.toUpperCase(),i=`${r?`${D(oe,r)} `:""}${se(o)} ${t}`;return n&&Object.keys(n).length>0&&(i+=` ${D(oe,Ce(n))}`),i}function Dn(e){return new Date(e[0]*1e3).toTimeString().slice(0,8)}function Mn(e){return`${se("AUTH")} ${e}`}function Fn(e,t,n,r,o){let s=n===void 0?"ERR":String(n),i=D(o==="error"?Ye:Xe,s);return`${se("API")} ${e} ${t} \u2192 ${i} ${D(oe,`${r}ms`)}`}function Ln(e){return`${se("AGENT")} ${D(Qe,e)}`}function Nn(e,t,n,r){let o=t==="error"?Ye:t==="awaiting-approval"?as:Xe,s=n!==void 0?`${D(oe,`${n} step${n===1?"":"s"}`)} `:"";return`${se("AGENT")} ${D(Qe,e)} \u2192 ${D(o,t)} ${s}${D(oe,`${r}ms`)}`}function Un(e,t,n){let r=t==="error"?D(Ye,"error"):D(Xe,"ok");return`${se("TOOL")} ${e} \u2192 ${r} ${D(oe,`${n}ms`)}`}function $n(e,t,n){let r=t?Ye:Xe,o=D(r,"\u25CF"),s=D(r,t?"error":"success");return`${o} ${D(Qe,e)} ${s} ${D(oe,`${n}ms`)}`}function H(e){try{process.stdout.write(e+`
|
|
3
3
|
`)}catch{}}var Kn=new Bn,gs=new Bn;function O(e){let t=gs.getStore();t&&(t[e]=!0)}var ys=/^[0-9a-f]{32}$/;function hs(e){let t=e.replace(/-/g,"").toLowerCase();return ys.test(t)?t:null}var ws={0:"STATUS_CODE_UNSET",1:"STATUS_CODE_OK",2:"STATUS_CODE_ERROR"},me=new Map;function Hn(e,t,n){let r=me.get(e);r?r[t]=n:me.set(e,{[t]:n})}function q(e,t,n){e.setAttribute(t,k(n))}var Pe;function jn(e){return`${e[0]}${String(e[1]).padStart(9,"0")}`}function kt(e){return Math.round(e[0]*1e3+e[1]/1e6)}function qn(e){try{process.stdout.write(Ce(e)+`
|
|
4
4
|
`)}catch{}}var Pt=class{export(t,n){for(let r of t){let o=r.spanContext().spanId,s=me.get(o),i={...r.attributes};if(s!==void 0){for(let[l,u]of Object.entries(s))typeof u=="string"?i[l]=re(u):typeof u=="object"&&u!==null?i[l]=k(u):i[l]=u;me.delete(o)}let a=Kn.getStore(),c=a?hs(a):null;qn({_otel:"span",traceId:c??r.spanContext().traceId,spanId:o,parentSpanId:r.parentSpanContext?.spanId??"",name:r.name,kind:r.kind,startTimeUnixNano:jn(r.startTime),endTimeUnixNano:jn(r.endTime),attributes:i,status:{code:ws[r.status.code]??"STATUS_CODE_UNSET",...r.status.message?{message:re(r.status.message)}:{}}})}n({code:ds.SUCCESS})}forceFlush(){return Promise.resolve()}shutdown(){return Promise.resolve()}},Ot=class{onStart(t,n){}onEnd(t){me.delete(t.spanContext().spanId)}forceFlush(){return Promise.resolve()}shutdown(){return Promise.resolve()}},_t=class{onStart(t){let n=t;(n.name==="function"||n.name==="App")&&H(`
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var b="X-Helix-Project-Execution-Token",R="X-Tray-Token",q={mode:"dev",deploymentId:null},k={...q},p={};function te(e){let{internalJwt:r,helixExecutionJwt:t,devToken:n,...i}=e;"internalJwt"in e&&(p.internalJwt=r),"helixExecutionJwt"in e&&(p.helixExecutionJwt=t),"devToken"in e&&(p.devToken=n);let o="userId"in e||"executionId"in e?{userEmail:void 0,userName:void 0}:{};k={...k,...o,...i}}function ne(){return k}function S(){return p.internalJwt}function P(){return p.helixExecutionJwt}function I(){return p.devToken}var O=new Set(["us1","eu1","ap1","ap2"]),s=new Map,h={name:"us1",exposedName:"us1",displayName:"us1",hosts:{api:"https://api.tray.io",broker:"https://api.tray.io/private/v1/code",ingest:"https://api.tray.io/private/v1/helix/otlp",weaver:"https://weaver.tray.io",app:"https://app.tray.io",projectHost:"helix-app.ai",dashboard:"https://app.helix.tray.ai",auth:"https://auth.tray.io"},login:{storePrefix:"PROD",appUrl:"https://app.tray.io",cookieName:"prod_tray_lid",cookieDomain:"tray.io"}},v={name:"eu1",exposedName:"eu1",displayName:"eu1",hosts:{api:"https://api.eu1.tray.io",broker:"https://api.eu1.tray.io/private/v1/code",ingest:"https://api.eu1.tray.io/private/v1/helix/otlp",weaver:"https://weaver.eu1.tray.io",app:"https://app.eu1.tray.io",projectHost:"eu1.helix-app.ai",dashboard:"https://app.helix.eu1.tray.ai",auth:"https://auth.eu1.tray.io"},login:{storePrefix:"EU1",appUrl:"https://app.eu1.tray.io",cookieName:"prod_tray_lid_eu",cookieDomain:"tray.io"}},x={name:"ap1",exposedName:"ap1",displayName:"ap1",hosts:{api:"https://api.ap1.tray.io",broker:"https://api.ap1.tray.io/private/v1/code",ingest:"https://api.ap1.tray.io/private/v1/helix/otlp",weaver:"https://weaver.ap1.tray.io",app:"https://app.ap1.tray.io",projectHost:"ap1.helix-app.ai",dashboard:"https://app.helix.ap1.tray.ai",auth:"https://auth.ap1.tray.io"},login:{storePrefix:"AP1",appUrl:"https://app.ap1.tray.io",cookieName:"prod_tray_lid_ap",cookieDomain:"tray.io"}},E={name:"ap2",exposedName:"ap2",displayName:"ap2",hosts:{api:"https://api.ap2.tray.io",broker:"https://api.ap2.tray.io/private/v1/code",ingest:"https://api.ap2.tray.io/private/v1/helix/otlp",weaver:"https://weaver.ap2.tray.io",app:"https://app.ap2.tray.io",projectHost:"ap2.helix-app.ai",dashboard:"https://app.helix.ap2.tray.ai",auth:"https://auth.ap2.tray.io"},login:{storePrefix:"AP2",appUrl:"https://app.ap2.tray.io",cookieName:"prod_tray_lid_ap2",cookieDomain:"tray.io"}};s.set(h.name,h);s.set(v.name,v);s.set(x.name,x);s.set(E.name,E);var T=["api","broker","ingest","weaver","app","projectHost","dashboard"],N=["auth"],D=["storePrefix","appUrl","cookieName","cookieDomain"];function C(e){if(!e.name||typeof e.name!="string")throw new Error("RegionProfile.name must be a non-empty string");if(!e.exposedName||typeof e.exposedName!="string")throw new Error("RegionProfile.exposedName must be a non-empty string");if(!e.displayName||typeof e.displayName!="string")throw new Error("RegionProfile.displayName must be a non-empty string");if(!e.hosts||typeof e.hosts!="object")throw new Error("RegionProfile.hosts must be an object");if(!e.login||typeof e.login!="object")throw new Error("RegionProfile.login must be an object");for(let r of T)if(typeof e.hosts[r]!="string"||!e.hosts[r])throw new Error(`RegionProfile.hosts.${r} must be a non-empty string`);for(let r of N){let t=e.hosts[r];if(t!==void 0&&(typeof t!="string"||!t))throw new Error(`RegionProfile.hosts.${r} must be a non-empty string when set`)}for(let r of D)if(typeof e.login[r]!="string"||!e.login[r])throw new Error(`RegionProfile.login.${r} must be a non-empty string`)}function j(e,r){return e.name===r.name&&e.exposedName===r.exposedName&&e.displayName===r.displayName&&T.every(t=>e.hosts[t]===r.hosts[t])&&N.every(t=>e.hosts[t]===r.hosts[t])&&D.every(t=>e.login[t]===r.login[t])}function oe(e){C(e);let r=s.get(e.name);if(r){if(j(r,e))return;throw new Error(`RegionProfile.name "${e.name}" is already registered with different values`)}for(let t of s.values())if(t.exposedName===e.exposedName)throw new Error(`RegionProfile.exposedName "${e.exposedName}" is already used by "${t.name}"`);s.set(e.name,e)}function H(e){return s.has(e)}function se(e){return s.get(e)}function m(e){let r=s.get(e);if(!r)throw new Error(`Unknown region: ${e}`);return r}function ae(){return[...s.keys()]}function de(){return[...s.values()].map(e=>e.exposedName)}function F(e){for(let r of s.values())if(r.exposedName===e)return r.name}var f=Symbol.for("@trayai/helix-sdk.forcedEnvironment");function B(e){let r=globalThis;if(e===void 0||e.trim()===""){delete r[f];return}let t=e.trim(),n=F(t);if(n){r[f]=n;return}if(H(t)){r[f]=t;return}throw new Error(`Unknown region: ${t}`)}function le(){return globalThis[f]}function ue(){return[...s.values()].filter(e=>!O.has(e.name))}function ce(){B(void 0),s.clear();for(let e of[h,v,x,E])s.set(e.name,{...e,hosts:{...e.hosts},login:{...e.login}})}var u=class e extends Error{detail;constructor(r){super(L(r)),this.name="SdkError",this.detail=r}get kind(){return this.detail.kind}static unknownAlias(r,t){return new e({kind:"unknown_alias",alias:r,available:t})}static inputValidationFailed(r){return new e({kind:"input_validation_failed",fields:r})}static outputValidationFailed(r){return new e({kind:"output_validation_failed",fields:r})}static configLoadFailed(r){return new e({kind:"config_load_failed",cause:r})}static brokerError(r,t,n,i){return new e({kind:"broker_error",status:r,message:t,body:n,code:i})}static unsupportedBodyType(r){return new e({kind:"unsupported_body_type",actualType:r})}static unsupportedScheme(r){return new e({kind:"unsupported_scheme",scheme:r})}static missingExecutionCredentials(){return new e({kind:"missing_execution_credentials"})}static missingTrayToken(){return new e({kind:"missing_tray_token"})}static dbCallFailed(r,t){return new e({kind:"db_call_failed",message:r,cause:t})}static dbQueryFailed(r){return new e({kind:"db_query_failed",message:r})}static dbInvalidParameters(r){return new e({kind:"db_invalid_parameters",message:r})}static kvKeyInvalid(r){return new e({kind:"kv_key_invalid",message:r})}static kvValueInvalid(r){return new e({kind:"kv_value_invalid",message:r})}static kvValueTooLarge(r,t){return new e({kind:"kv_value_too_large",message:r,maxBytes:t})}static kvTtlInvalid(r){return new e({kind:"kv_ttl_invalid",message:r})}static kvNotAvailable(){return new e({kind:"kv_not_available"})}static kvCallFailed(r,t,n){return new e({kind:"kv_call_failed",status:r,message:t,body:n})}static kvRequiresProvisioning(){return new e({kind:"kv_requires_provisioning"})}static filesPathInvalid(r){return new e({kind:"files_path_invalid",message:r})}static filesValueInvalid(r){return new e({kind:"files_value_invalid",message:r})}static filesValueTooLarge(r,t){return new e({kind:"files_value_too_large",message:r,maxBytes:t})}static filesNotAvailable(){return new e({kind:"files_not_available"})}static filesCallFailed(r,t,n){return new e({kind:"files_call_failed",status:r,message:t,body:n})}static filesRequiresProvisioning(){return new e({kind:"files_requires_provisioning"})}static callFunctionPathInvalid(r){return new e({kind:"call_function_path_invalid",message:r})}static callFunctionCallFailed(r,t,n){return new e({kind:"call_function_call_failed",status:r,message:t,body:n})}static callFunctionRequiresProvisioning(){return new e({kind:"call_function_requires_provisioning"})}static callFunctionNotAvailable(){return new e({kind:"call_function_not_available"})}static callFunctionMissingExecutionJwt(){return new e({kind:"call_function_missing_execution_jwt"})}static aiUnsupportedService(r,t,n){return new e({kind:"ai_unsupported_service",alias:r,service:t,supported:n})}static aiModelIdRequired(r,t){return new e({kind:"ai_model_id_required",alias:r,operation:t})}static aiModelInstanceRequired(r){return new e({kind:"ai_model_instance_required",modelId:r})}static aiProviderNotConfigured(r,t){return new e({kind:"ai_provider_not_configured",alias:r,supported:t})}static aiProviderMisconfigured(r,t,n){return new e({kind:"ai_provider_misconfigured",alias:r,service:t,message:n})}static aiForeignModelRejected(){return new e({kind:"ai_foreign_model_rejected"})}static agentSessionsFailed(r){return new e({kind:"agent_sessions_failed",message:r})}};function ge(e){return e instanceof u}function L(e){switch(e.kind){case"unknown_alias":return`Unknown auth alias "${e.alias}". Available: ${e.available.join(", ")||"(none)"}`;case"input_validation_failed":return`Input validation failed for fields: ${e.fields.join(", ")}`;case"output_validation_failed":return`Output validation failed for fields: ${e.fields.join(", ")}`;case"config_load_failed":return`Config load failed: ${e.cause}`;case"broker_error":return e.code?`broker error: ${e.status} ${e.code}: ${e.message}`:`broker error: ${e.status} ${e.message}`;case"unsupported_body_type":return`unsupported body type: ${e.actualType}`;case"unsupported_scheme":return`unsupported scheme: ${e.scheme} (only https supported)`;case"missing_execution_credentials":return"missing execution credentials: at least one of internalJwt / helixExecutionJwt must be set before an authed broker/KV call";case"missing_tray_token":return"Not logged in. Run `helix login` to authenticate before making authed HTTP calls in dev.";case"db_call_failed":return`Database call failed: ${e.message}`;case"db_query_failed":return`Database query failed: ${e.message}`;case"db_invalid_parameters":return`Invalid database parameters: ${e.message}`;case"kv_key_invalid":return`Invalid KV key: ${e.message}`;case"kv_value_invalid":return e.message;case"kv_value_too_large":return e.message;case"kv_ttl_invalid":return e.message;case"kv_not_available":return"Key-value store is not available in this environment";case"kv_call_failed":return`KV platform error: ${e.status} ${e.message}`;case"kv_requires_provisioning":return"Key-value store requires a provisioned project (run helix project set)";case"files_path_invalid":return`Invalid file path: ${e.message}`;case"files_value_invalid":return e.message;case"files_value_too_large":return e.message;case"files_not_available":return"File storage is not available in this environment";case"files_call_failed":return`Files platform error: ${e.status} ${e.message}`;case"files_requires_provisioning":return"File storage requires a provisioned project (run helix project set)";case"call_function_path_invalid":return`Invalid function path: ${e.message}`;case"call_function_call_failed":return`Async function call failed: ${e.status} ${e.message}`;case"call_function_requires_provisioning":return"callFunctionAsync requires a provisioned project (run helix project set)";case"call_function_not_available":return"callFunctionAsync is not available: no running dev server was found";case"call_function_missing_execution_jwt":return"ctx.callFunctionAsync requires a helix project-execution JWT \u2014 a legacy internalJwt-only execution cannot call it";case"ai_unsupported_service":return`Authentication alias "${e.alias}" resolves to service "${e.service}", which ctx.ai does not support. Supported AI services: ${e.supported.join(", ")}`;case"ai_model_id_required":return`ctx.ai("${e.alias}").${e.operation} requires \`model\` as a string model id. To pass a model instance, use the top-level ctx.ai.${e.operation} instead.`;case"ai_model_instance_required":return`ctx.ai.* call functions require a model instance from ctx.ai(alias), got the string "${e.modelId}". Bare model ids would route outside the credentials broker and are not supported.`;case"ai_provider_not_configured":return`No AI provider configured for authentication alias "${e.alias}". Add \`aiProviders: { "${e.alias}": "<service>" }\` to helix.config.ts (supported services: ${e.supported.join(", ")}; bedrock needs the object form with region, openai-compatible the object form with baseUrl).`;case"ai_provider_misconfigured":return`aiProviders entry for authentication alias "${e.alias}" (service "${e.service}") is incomplete: ${e.message}`;case"ai_foreign_model_rejected":return"ctx.ai.* call functions require a model instance minted by ctx.ai(alias). A model built directly against a raw @ai-sdk/* provider carries its own transport and credentials, and would bypass the credentials broker, proxy policy, and metering.";case"agent_sessions_failed":return`Agent session store error: ${e.message}`}}import{z as g}from"zod";var A="x-helix-destination-url",U="x-helix-authentication-id",J="x-helix-deployment-id",_="x-execution-id",M="x-helix-broker-error",he="route_not_found",K=new Set([A,U,J,"authorization","x-tray-token","x-helix-project-execution-token","host","content-length","connection","transfer-encoding","te","upgrade","keep-alive","expect","proxy-authorization","proxy-connection","accept-encoding","x-request-id",_]);function V(e){let r=e.toLowerCase();return K.has(r)||r.startsWith("x-tray-internal-")}var w=g.object({error:g.object({code:g.string(),message:g.string(),issues:g.array(g.unknown()).optional()})});function ve(e,r){let t=`${m(e).hosts.api}/private/v1/helix/broker/http/raw`;return r==="dev"?`${t}/dev`:t}function xe(e){if(e.mode==="lambda"){let t=S(),n=P(),i=!!(t&&t.trim().length>0),o=!!(n&&n.trim().length>0);if(!i&&!o)throw u.missingExecutionCredentials();let a={};return i&&(a[R]=t),o&&(a[b]=n),{headers:a,deploymentId:e.deploymentId??null}}let r=I();if(!r)throw u.missingTrayToken();return{headers:{Authorization:`Bearer ${r}`},deploymentId:null}}function G(e){return typeof e=="string"||e instanceof ArrayBuffer||ArrayBuffer.isView(e)||typeof Blob<"u"&&e instanceof Blob||typeof FormData<"u"&&e instanceof FormData||e instanceof URLSearchParams||typeof ReadableStream<"u"&&e instanceof ReadableStream}function Ee(e){let r=new URL(e.url);if(r.protocol!=="https:")throw u.unsupportedScheme(r.protocol.replace(/:$/,""));if(e.query!==void 0)if(e.query instanceof URLSearchParams)for(let[l,d]of e.query.entries())r.searchParams.append(l,d);else for(let[l,d]of Object.entries(e.query))for(let $ of Array.isArray(d)?d:[d])r.searchParams.append(l,$);let t;e.headers===void 0?t=[]:e.headers instanceof Headers?t=Array.from(e.headers.entries()):Array.isArray(e.headers)?t=e.headers:t=Object.entries(e.headers);let n=t.filter(([l])=>!V(l)),i=e.body!==void 0&&e.body!==null,o,a,c=!1;return i&&(G(e.body)?(o=e.body,c=typeof ReadableStream<"u"&&e.body instanceof ReadableStream):(o=JSON.stringify(e.body),n.some(([d])=>d.toLowerCase()==="content-type")||(a="application/json"))),{authenticationId:e.authenticationId,method:e.method.toUpperCase(),destinationUrl:r.toString(),headers:n,body:o,isStreamBody:c,defaultContentType:a}}async function X(e,r){let t=await e.text(),n=t,i=t||r;try{n=JSON.parse(t);let o=w.safeParse(n);o.success&&(i=o.data.error.message)}catch{}return{status:e.status,code:r,message:i,body:n}}var Y=6e4;function z(e){return e.includes("json")}function W(e){return e.startsWith("text/")||e.includes("xml")||e.includes("urlencoded")||e.includes("javascript")||e.includes("ecmascript")}function Q(e,r){if(e.byteLength===0)return;let t=r.toLowerCase();if(z(t)){let n=new TextDecoder("utf-8").decode(e);try{return JSON.parse(n)}catch{return n}}return W(t)?new TextDecoder("utf-8").decode(e):e}function Z(e){let r={};for(let[t,n]of e.entries())r[t.toLowerCase()]=n;return r}async function we(e){let{request:r}=e,t=new Headers;for(let[l,d]of r.headers)t.append(l,d);r.defaultContentType&&!t.has("content-type")&&t.set("content-type",r.defaultContentType),t.set(A,r.destinationUrl),t.set(U,r.authenticationId);for(let[l,d]of Object.entries(e.credentialHeaders))t.set(l,d);e.executionId&&t.set(_,e.executionId);let n={method:r.method,headers:t,redirect:"manual",signal:AbortSignal.timeout(e.timeoutMs??Y)};r.body!==void 0&&(n.body=r.body,r.isStreamBody&&(n.duplex="half"));let i=await fetch(e.proxyUrl,n),o=i.headers.get(M);if(o!==null)return{kind:"brokerError",...await X(i,o)};let a=new Uint8Array(await i.arrayBuffer()),c=i.headers.get("content-type")??"";return{kind:"upstream",response:{status:i.status,headers:Z(i.headers),body:Q(a,c)}}}import{z as y}from"zod";var ee=3e4;function Te(e){let r=new URL(e);if(r.protocol!=="https:")throw u.unsupportedScheme(r.protocol.replace(/:$/,""))}function Ne(e,r){let t=`${m(e).hosts.api}/private/v1/helix/broker/s3/sign`;return r==="dev"?`${t}/dev`:t}var re=y.object({url:y.string(),method:y.string(),expiresAt:y.string()});async function De(e){let r=new Headers({"content-type":"application/json"});for(let[a,c]of Object.entries(e.credentialHeaders))r.set(a,c);e.executionId&&r.set(_,e.executionId);let t=await fetch(e.signUrl,{method:"POST",headers:r,body:JSON.stringify(e.body),redirect:"manual",signal:AbortSignal.timeout(e.timeoutMs??ee)}),n=await t.text(),i=n;try{i=JSON.parse(n)}catch{}if(t.ok){let a=re.safeParse(i);return a.success?{kind:"signed",result:a.data}:{kind:"brokerError",status:t.status,message:"malformed s3-sign response from credential broker",body:i}}let o=w.safeParse(i);return o.success?{kind:"brokerError",status:t.status,code:o.data.error.code,message:o.data.error.message,body:i}:{kind:"brokerError",status:t.status,message:n||`s3-sign request failed with status ${t.status}`,body:i}}export{b as a,R as b,te as c,ne as d,S as e,P as f,oe as g,H as h,se as i,m as j,ae as k,de as l,F as m,B as n,le as o,ue as p,ce as q,u as r,ge as s,A as t,U as u,J as v,_ as w,M as x,he as y,V as z,w as A,ve as B,xe as C,Ee as D,X as E,Y as F,we as G,Te as H,Ne as I,De as J};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z, ZodType } from 'zod';
|
|
2
|
-
import { P as PlatformContext } from './types-
|
|
2
|
+
import { P as PlatformContext } from './types-BSbvztCi.js';
|
|
3
3
|
|
|
4
4
|
interface SdkRuntimeConfig {
|
|
5
5
|
/**
|
|
@@ -20,6 +20,20 @@ interface SdkRuntimeConfig {
|
|
|
20
20
|
* `x-tray-user-id` header.
|
|
21
21
|
*/
|
|
22
22
|
userId?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Email of the calling user for the current invocation. Set via
|
|
25
|
+
* `setSdkConfig(...)` at handler entry in lambda mode. In `dev` mode,
|
|
26
|
+
* define-function reads from the `x-tray-user-email` header. Only exposed
|
|
27
|
+
* on `ctx.identity` when `userId` is also set.
|
|
28
|
+
*/
|
|
29
|
+
userEmail?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Display name of the calling user for the current invocation. Set via
|
|
32
|
+
* `setSdkConfig(...)` at handler entry in lambda mode. In `dev` mode,
|
|
33
|
+
* define-function reads from the `x-tray-user-name` header. Only exposed
|
|
34
|
+
* on `ctx.identity` when `userId` is also set.
|
|
35
|
+
*/
|
|
36
|
+
userName?: string;
|
|
23
37
|
/**
|
|
24
38
|
* Deployment ID for the current invocation. Set via `setSdkConfig(...)` at
|
|
25
39
|
* handler entry. Only meaningful in `lambda` mode; `dev` mode has no
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as h3 from 'h3';
|
|
2
2
|
import { ZodType } from 'zod';
|
|
3
|
-
import { F as FunctionHandler, D as DefineFunctionOptions, a as DefineScheduleConfig, S as ScheduleDefinition, P as PlatformContext } from './types-
|
|
4
|
-
export { A as AgentApprovalDecision, b as AgentCallOptions, c as AgentClient, d as AgentPendingApproval, e as AgentResult, f as AgentSession, g as AgentSessionPage, h as AgentSessionPageOptions, i as AgentSessionSummary, j as AgentSessionsList, k as AgentStreamResult, l as AiEmbeddingModelInstance, m as AiImageModelInstance, n as AiLanguageModelInstance, o as AiSpeechModelInstance, p as AiTranscriptionModelInstance, B as BrokerAuthedClient, q as BrokerCallOptions, r as BrokerCallResult, C as CallFunctionAsync, s as DbCallParameters, t as DbClient, u as FileSystemClient, H as HelixAI, v as HelixAIProvider, w as HelixAgent, x as HelixCost, y as HelixResultMeta, z as HttpClient, K as KeyValueStore, L as Logger, E as S3SignOptions, G as S3SignResult, I as ScheduleContext, J as ScheduleHandler, M as ScheduleTrigger, N as SqlBuilder, T as TrayContext, U as UnvalidatedInput } from './types-
|
|
5
|
-
import { T as TrayConfig, L as LoadedTrayConfig, W as WatchErrorPhase } from './define-agent-
|
|
6
|
-
export { A as AGENT_DEFINITION_KIND, a as AI_SERVICES, b as AgentDefinition, c as AgentDefinitionConfig, d as AgentSessionsConfig, e as AiProviderEntry, f as AiService, C as ConfigFileOptions, D as DefineToolConfig, H as HELIX_CONFIG_ENV, g as HelixTool, h as HelixToolLike, P as ProvisionedTrayConfig, S as SdkRuntimeConfig, i as TOOL_DEFINITION_KIND, U as UnprovisionedTrayConfig, j as WORKSPACE_ID_REQUIRED_CODE, k as WorkspaceIdRequiredError, l as agentSessionsSchema, m as aiProviderEntrySchema, n as defineAgent, o as defineTool, p as getSdkConfig, q as isAgentDefinition, r as isToolDefinition, s as loadConfig, t as loadedTrayConfigSchema, u as projectIdSchema, v as requireWorkspaceId, w as resolveConfigFile, x as resolveConfigOverride, y as workspaceIdSchema } from './define-agent-
|
|
3
|
+
import { F as FunctionHandler, D as DefineFunctionOptions, a as DefineScheduleConfig, S as ScheduleDefinition, P as PlatformContext } from './types-BSbvztCi.js';
|
|
4
|
+
export { A as AgentApprovalDecision, b as AgentCallOptions, c as AgentClient, d as AgentPendingApproval, e as AgentResult, f as AgentSession, g as AgentSessionPage, h as AgentSessionPageOptions, i as AgentSessionSummary, j as AgentSessionsList, k as AgentStreamResult, l as AiEmbeddingModelInstance, m as AiImageModelInstance, n as AiLanguageModelInstance, o as AiSpeechModelInstance, p as AiTranscriptionModelInstance, B as BrokerAuthedClient, q as BrokerCallOptions, r as BrokerCallResult, C as CallFunctionAsync, s as DbCallParameters, t as DbClient, u as FileSystemClient, H as HelixAI, v as HelixAIProvider, w as HelixAgent, x as HelixCost, y as HelixResultMeta, z as HttpClient, K as KeyValueStore, L as Logger, E as S3SignOptions, G as S3SignResult, I as ScheduleContext, J as ScheduleHandler, M as ScheduleTrigger, N as SqlBuilder, T as TrayContext, U as UnvalidatedInput } from './types-BSbvztCi.js';
|
|
5
|
+
import { T as TrayConfig, L as LoadedTrayConfig, W as WatchErrorPhase } from './define-agent-BEUgQ_5-.js';
|
|
6
|
+
export { A as AGENT_DEFINITION_KIND, a as AI_SERVICES, b as AgentDefinition, c as AgentDefinitionConfig, d as AgentSessionsConfig, e as AiProviderEntry, f as AiService, C as ConfigFileOptions, D as DefineToolConfig, H as HELIX_CONFIG_ENV, g as HelixTool, h as HelixToolLike, P as ProvisionedTrayConfig, S as SdkRuntimeConfig, i as TOOL_DEFINITION_KIND, U as UnprovisionedTrayConfig, j as WORKSPACE_ID_REQUIRED_CODE, k as WorkspaceIdRequiredError, l as agentSessionsSchema, m as aiProviderEntrySchema, n as defineAgent, o as defineTool, p as getSdkConfig, q as isAgentDefinition, r as isToolDefinition, s as loadConfig, t as loadedTrayConfigSchema, u as projectIdSchema, v as requireWorkspaceId, w as resolveConfigFile, x as resolveConfigOverride, y as workspaceIdSchema } from './define-agent-BEUgQ_5-.js';
|
|
7
7
|
export { a as REGION_VALUES, R as Region, r as regionSchema } from './region-schema-COfWyGI9.js';
|
|
8
8
|
import { StopCondition, ToolSet } from 'ai';
|
|
9
9
|
export { EmbedManyResult, EmbedResult, EmbeddingModel, FinishReason, GenerateImageResult, GenerateObjectResult, GenerateTextResult, ImageModel, LanguageModel, LanguageModelUsage, ModelMessage, Output, PrepareStepFunction, SpeechModel, SpeechResult, StopCondition, StreamObjectResult, StreamTextResult, TextStreamPart, ToolChoice, ToolSet, TranscriptionModel, TranscriptionResult, UIMessage, convertToModelMessages, cosineSimilarity, dynamicTool, hasToolCall, jsonSchema, smoothStream, stepCountIs, tool, zodSchema } from 'ai';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{A as
|
|
2
|
-
`)}function
|
|
1
|
+
import{A as pe,B as ge,C as me,D as he,E as ye,F as Ce,G as ve,H as k,I as T,J as B,K as G,L as C,M as Se,N as Ee,O as J,P as we,Q as _e,R as xe,Y as ke,Z as Te,_ as be,ba as Ie,ca as Q,da as Re,ea as Ae,f as H,fa as Pe,g as x,ga as He,h as F,i as y,j as D,k as O,l as L,m as j,n as ue,o as W,p as N,q as Z,r as K,s as $,w as V,x as z,y as le,z as fe}from"./chunk-GMEVZH35.js";import{a as M,b as ce}from"./chunk-WUCX7RZO.js";import{d as _,r as U,s as q}from"./chunk-LKZKDHYO.js";import{randomUUID as Ue}from"crypto";import{SpanStatusCode as re,SpanKind as qe}from"@opentelemetry/api";import{defineEventHandler as Ze,getMethod as Ke,getRequestURL as $e,getHeaders as ne,getHeader as E}from"h3";import{readBody as Fe,getQuery as De,getRouterParams as Oe}from"h3";async function X(e,t){let r=await Le(e),n=De(e),o=Oe(e)??{},s={...n,...r,...o};return t?je(s,t):s}async function Le(e){try{let t=await Fe(e);return t&&typeof t=="object"?t:(t!=null&&t!==""&&console.warn("[helix-sdk] Request body present but not a JSON object \u2014 ignored"),{})}catch(t){if(t instanceof Error&&"statusCode"in t&&t.statusCode===400){let n=new Error("Malformed request body");throw n.statusCode=400,n.data={message:"Request body is not valid JSON"},n}let r=e.method?.toUpperCase();if(r==="GET"||r==="HEAD"||r==="DELETE")return{};throw t}}function je(e,t){let r=t.safeParse(e);if(!r.success){let n=new Error("Input validation failed");throw n.statusCode=400,n.data=r.error.flatten(),n}return r.data}var v=class extends Error{statusCode;constructor(t,r){super(r),this.statusCode=t,this.name="HttpError"}};function Y(e){return t=>{e.node.res.statusCode=t}}function ee(){return(e,t)=>{throw new v(e,t)}}function te(e,t){let{statusCode:r,message:n}=Me(t.detail);return e.node.res.statusCode=r,{error:n,statusCode:r}}function Me(e){switch(e.kind){case"unknown_alias":return{statusCode:400,message:"Unknown authentication alias"};case"input_validation_failed":return{statusCode:400,message:"Input validation failed"};case"output_validation_failed":return{statusCode:500,message:"Internal server error"};case"config_load_failed":return{statusCode:500,message:"Configuration error"};case"broker_error":return{statusCode:502,message:"Broker error"};case"unsupported_body_type":return{statusCode:400,message:"Unsupported request body type"};case"unsupported_scheme":return{statusCode:400,message:"Unsupported URL scheme"};case"missing_execution_credentials":return{statusCode:401,message:"Missing execution credentials"};case"missing_tray_token":return{statusCode:500,message:"Missing Tray token"};case"db_call_failed":return{statusCode:502,message:e.message};case"db_query_failed":return{statusCode:502,message:`Database query failed: ${e.message}`};case"db_invalid_parameters":return{statusCode:400,message:e.message};case"kv_key_invalid":return{statusCode:400,message:e.message};case"kv_value_invalid":return{statusCode:400,message:e.message};case"kv_value_too_large":return{statusCode:400,message:e.message};case"kv_ttl_invalid":return{statusCode:400,message:e.message};case"kv_not_available":return{statusCode:501,message:"Key-value store is not available in this environment"};case"kv_call_failed":return{statusCode:502,message:"Key-value store request failed"};case"kv_requires_provisioning":return{statusCode:500,message:"Internal server error"};case"files_path_invalid":return{statusCode:400,message:e.message};case"files_value_invalid":return{statusCode:400,message:e.message};case"files_value_too_large":return{statusCode:400,message:e.message};case"files_not_available":return{statusCode:501,message:"File storage is not available in this environment"};case"files_call_failed":return{statusCode:502,message:"File storage request failed"};case"files_requires_provisioning":return{statusCode:500,message:"Internal server error"};case"call_function_path_invalid":return{statusCode:400,message:e.message};case"call_function_call_failed":return{statusCode:502,message:"Async function call failed"};case"call_function_requires_provisioning":return{statusCode:500,message:"Internal server error"};case"call_function_not_available":return{statusCode:501,message:"callFunctionAsync is not available in this environment"};case"call_function_missing_execution_jwt":return{statusCode:401,message:"Missing execution credentials"};case"ai_unsupported_service":case"ai_provider_misconfigured":case"ai_model_id_required":case"ai_model_instance_required":case"ai_provider_not_configured":case"ai_foreign_model_rejected":case"agent_sessions_failed":return{statusCode:500,message:e.kind==="ai_unsupported_service"?`AI service not supported for alias "${e.alias}"`:e.kind==="ai_provider_misconfigured"?`AI provider misconfigured for alias "${e.alias}"`:"Internal server error"};default:return{statusCode:500,message:`Unhandled error kind: ${e.kind}`}}}var We=["authorization","x-tray-token","set-cookie","x-kong-request-id","traceparent","x-real-ip","x-tray-user-email","x-tray-user-name","cookie"];function Ne(e){return e.toLowerCase().includes("tray_lid")}function b(e){let t={};for(let[r,n]of Object.entries(e))if(!We.includes(r.toLowerCase())){if(r.toLowerCase()==="cookie"&&n){let o=n.split(";").map(s=>s.trim()).filter(s=>{let d=s.split("=")[0].trim();return!Ne(d)}).join("; ");o&&(t[r]=o);continue}t[r]=n}return t}function Ve(e,t){let{inputSchema:r,outputSchema:n}=Xe(t),o=e;return Ze(async s=>{let d=_(),{executionId:a,userId:i,userEmail:g,userName:c,deploymentId:l}=Ye(d,s),p=d.mode==="lambda"?d.parentExecutionId??null:null,f=Date.now(),u=new Date().toISOString(),m=Ke(s),h=$e(s).pathname,ie=N(),A=W(),ae=`${m} ${h}`;D();let P={hasDb:!1,hasExternal:!1,hasAuth:!1,hasAi:!1,hasError:!1};return ze(()=>x.run(P,()=>H.run(a,async()=>{let S=await Be(s,r);if(!S.ok)return{response:S.response,errored:!1,errorMessage:null};let de=tt(s,S.input,ie,A,m,h,a,l,i,g,c,p);return Ge(o,de,n,s,A,a,l,{method:m,path:h,rawInput:S.input})})),{executionId:a,deploymentId:l,routeOrJob:ae,startedAt:u,startMs:f,userId:i,flags:P})})}async function ze(e,t){let r=!1,n=null;try{let o=await e();return r=o.errored,n=o.errorMessage,o.response}finally{j({...t,errored:r,errorMessage:n}),await O()}}async function Be(e,t){try{return{ok:!0,input:await X(e,t)}}catch(r){let n=et(e,r);if(n)return{ok:!1,response:n};throw r}}async function Ge(e,t,r,n,o,s,d,a){return L.startActiveSpan("function",{root:!0,kind:qe.SERVER,attributes:{method:a.method,route:a.path,executionId:s,...d?{deploymentId:d}:{}}},async i=>{t.traceId=i.spanContext().traceId;let g=b(ne(n));y(i,"input",a.rawInput),y(i,"request",{method:a.method,path:a.path,headers:g,body:a.rawInput});let c=!1,l=null,p,f;try{let u=await M.run(t,()=>e(t));if(p=u,u==null)n.node.res.statusCode=204,f="";else if(u instanceof Response)f=u;else if(r){let m=r.safeParse(u);if(!m.success){let h=Object.keys(m.error.flatten().fieldErrors);throw o.error("Output validation failed",{fields:h,executionId:s}),U.outputValidationFailed(h)}f=m.data}else f=u}catch(u){c=!0,l=u instanceof Error?u.message:String(u),F("hasError"),f=Je(u,n,o,s)}finally{Qe(i,n,{errored:c,errorMessage:l,handlerResult:p,response:f})}return{response:f,errored:c,errorMessage:l}})}function Je(e,t,r,n){if(e instanceof v)return t.node.res.statusCode=e.statusCode,{error:e.message,statusCode:e.statusCode};if(q(e))return te(t,e);r.error("Unhandled error in handler",{error:e instanceof Error?e.message:String(e),executionId:n}),t.node.res.statusCode=500;let o=process.env.NODE_ENV==="development";return{error:o&&e instanceof Error?e.message:"Internal server error",statusCode:500,...o&&e instanceof Error&&e.stack?{stack:e.stack}:{}}}function Qe(e,t,r){e.setAttribute("statusCode",t.node.res.statusCode),!r.errored&&r.handlerResult!==void 0&&y(e,"output",r.handlerResult),y(e,"response",r.response);let n=x.getStore();e.setAttribute("hasAuth",n?.hasAuth??!1),e.setAttribute("hasAi",n?.hasAi??!1),e.setAttribute("hasExternal",n?.hasExternal??!1),e.setAttribute("hasDb",n?.hasDb??!1),e.setAttribute("status",r.errored?"error":"success");let o=r.errored||(n?.hasError??!1);e.setStatus({code:o?re.ERROR:re.OK,...r.errorMessage?{message:r.errorMessage}:{}}),e.end()}function Xe(e){if(!e)return{inputSchema:void 0,outputSchema:void 0};if(e instanceof Object&&"_def"in e)return{inputSchema:e,outputSchema:void 0};if(typeof e=="object"&&("input"in e||"output"in e)){let t=e;return{inputSchema:t.input,outputSchema:t.output}}return{inputSchema:e,outputSchema:void 0}}function Ye(e,t){let r=e.mode==="lambda",n=(r?e.executionId:E(t,"x-tray-execution-id"))??Ue(),o=(r?e.userId:E(t,"x-tray-user-id"))||null,s=(r?e.userEmail:E(t,"x-tray-user-email"))||null,d=(r?e.userName:E(t,"x-tray-user-name"))||null,a=r?e.deploymentId??null:null;return{executionId:n,userId:o,userEmail:s,userName:d,deploymentId:a}}function et(e,t){if(!(t instanceof Error)||!("statusCode"in t)||!("data"in t))return null;let r=t.statusCode,n=t.data;e.node.res.statusCode=r;let o=n&&typeof n=="object"&&"fieldErrors"in n?n.fieldErrors:void 0;return{error:"Input validation failed",statusCode:r,...o?{fields:Object.keys(o)}:{}}}function tt(e,t,r,n,o,s,d,a,i,g,c,l){return{input:t,method:o,path:s,headers:b(ne(e)),http:Z(),db:p=>K(p),kv:()=>$(),files:()=>V(),callFunctionAsync:z(),ai:J(),agent:p=>Q(p),log:n,config:r,status:Y(e),error:ee(),state:{},request:e,executionId:d,deploymentId:a,userId:i,parentExecutionId:l,identity:i!==null?{user:{id:i,email:g,name:c}}:null,traceId:""}}function rt(e){return e}import{existsSync as nt,watch as ot,writeSync as st}from"fs";import{basename as it,dirname as at,join as dt,resolve as w}from"path";import{watchConfig as ut}from"c12";function ct(e,t){let r=e instanceof Error?e.message:String(e);st(2,`[helix-watch] ${t.phase} error: ${r}
|
|
2
|
+
`)}function I(){return{kind:"unprovisioned",name:"",authentications:{},config:{},region:"us1"}}var lt=/^(?:helix|tray)\.config\.(?:m|c)?[jt]s$/,oe=new Set;function se(e,t){return T(e,{configFile:t})!==void 0}async function ft(e,t,r){if(se(e.cwd,t))try{return{current:await C(e.cwd,{configFile:t}),initialLoadSucceeded:!0}}catch(n){return r(n,{phase:"reload"}),{current:I(),initialLoadSucceeded:!1}}if(e.watch){let n=t!==void 0?w(e.cwd,t):w(e.cwd);oe.has(n)||(process.stderr.write(t!==void 0?`warning: config file ${w(e.cwd,t)} not found; tray running with default config
|
|
3
3
|
`:`warning: no helix.config.ts found at ${e.cwd}; tray running with default config \u2014 create one via \`helix init\`
|
|
4
|
-
`),
|
|
4
|
+
`),oe.add(n))}return{current:I(),initialLoadSucceeded:!1}}var R=class{constructor(t,r,n,o){this.cwd=t;this.configFile=r;this.onError=n;this.emit=o}cwd;configFile;onError;emit;stopped=!1;directoryWatcher=null;c12Unwatch=null;c12AttachPromise=null;updateChain=Promise.resolve();start(t){t?this.attachC12Watcher():this.attachCreationWatcher()}watcherReady(){return this.c12AttachPromise===null?Promise.resolve():this.c12AttachPromise.catch(()=>{})}async stop(){this.stopped=!0,this.directoryWatcher&&(this.directoryWatcher.close(),this.directoryWatcher=null),this.c12AttachPromise&&await this.c12AttachPromise.catch(t=>this.onError(t,{phase:"attach"})),this.c12Unwatch&&(await this.c12Unwatch(),this.c12Unwatch=null)}attachC12Watcher(){this.c12AttachPromise===null&&(this.c12AttachPromise=ut({...B(this.cwd,{configFile:this.configFile}),onUpdate:({newConfig:t})=>{this.stopped||(this.updateChain=this.updateChain.then(async()=>{if(this.stopped)return;let r;try{r=G(t.config,this.cwd)}catch(n){this.onError(n,{phase:"validation"});return}try{this.emit(r)}catch(n){this.onError(n,{phase:"reload"})}}))}}).then(async t=>{if(this.stopped){t.unwatch();return}this.c12Unwatch=t.unwatch;let{watch:r}=await import("chokidar"),n=r(this.cwd,{persistent:!1,depth:0});try{await new Promise((o,s)=>{n.once("ready",o),n.once("error",s)})}finally{await n.close()}}).catch(t=>{this.onError(t,{phase:"attach"})}))}attachCreationWatcher(){let t=this.configFile!==void 0?w(this.cwd,this.configFile):void 0,r=t!==void 0?at(t):this.cwd;try{this.directoryWatcher=ot(r,{persistent:!1},(n,o)=>{if(this.stopped||!o)return;let s=o.toString();if(t!==void 0){if(s!==it(t))return}else if(!lt.test(s))return;nt(dt(r,s))&&(this.updateChain=this.updateChain.then(async()=>{if(this.stopped)return;let d;try{d=await C(this.cwd,{configFile:this.configFile})}catch(i){this.onError(i,{phase:"reload"});return}if(this.stopped)return;this.emit(d);let a=this.directoryWatcher;a&&(this.directoryWatcher=null,a.close()),this.attachC12Watcher()}))}),this.directoryWatcher.on("error",n=>{this.onError(n,{phase:"attach"})})}catch(n){this.onError(n,{phase:"attach"})}}};async function pt(e){let t=e.onError??ct,r=new Set,n=k(e.configFile),o=await ft(e,n,t),s=o.current;function d(i){s=i;for(let g of[...r])try{g(i)}catch(c){t(c,{phase:"reload"})}}let a=new R(e.cwd,n,t,d);return e.watch&&a.start(o.initialLoadSucceeded),{get(){return s},async reload(){if(!se(e.cwd,n)){let i=I();return d(i),i}try{let i=await C(e.cwd,{configFile:n});return d(i),i}catch(i){return t(i,{phase:"reload"}),s}},subscribe(i){return r.add(i),()=>{r.delete(i)}},async stop(){r.clear(),await a.stop()},ready(){return a.watcherReady()}}}import{tool as ar,dynamicTool as dr,jsonSchema as ur,zodSchema as cr,stepCountIs as lr,hasToolCall as fr,convertToModelMessages as pr,cosineSimilarity as gr,smoothStream as mr,Output as hr}from"ai";export{ke as AGENT_DEFINITION_KIND,he as AI_SERVICES,ve as HELIX_CONFIG_ENV,hr as Output,le as REGION_VALUES,Re as SCHEDULE_DEFINITION_KIND,Ae as ScheduleConfigError,we as TOOL_DEFINITION_KIND,Se as WORKSPACE_ID_REQUIRED_CODE,me as agentSessionsSchema,ye as aiProviderEntrySchema,pr as convertToModelMessages,gr as cosineSimilarity,pt as createConfigService,Te as defineAgent,rt as defineConfig,Ve as defineFunction,Pe as defineSchedule,_e as defineTool,dr as dynamicTool,ce as getContext,_ as getSdkConfig,fr as hasToolCall,be as isAgentDefinition,He as isScheduleDefinition,xe as isToolDefinition,ur as jsonSchema,C as loadConfig,Ce as loadedTrayConfigSchema,pe as projectIdSchema,fe as regionSchema,Ee as requireWorkspaceId,T as resolveConfigFile,k as resolveConfigOverride,ue as runWithinAppSpan,mr as smoothStream,lr as stepCountIs,ar as tool,Ie as totalToolCallsIs,ge as workspaceIdSchema,cr as zodSchema};
|
package/dist/internal/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { L as LoadedTrayConfig, b as AgentDefinition } from '../define-agent-
|
|
2
|
-
export { z as SdkConfigInput, B as setSdkConfig } from '../define-agent-
|
|
3
|
-
import { j as AgentSessionsList, b as AgentCallOptions, e as AgentResult } from '../types-
|
|
4
|
-
export { O as SessionExpiredError, Q as clearAgentSessions } from '../types-
|
|
1
|
+
import { L as LoadedTrayConfig, b as AgentDefinition } from '../define-agent-BEUgQ_5-.js';
|
|
2
|
+
export { z as SdkConfigInput, B as setSdkConfig } from '../define-agent-BEUgQ_5-.js';
|
|
3
|
+
import { j as AgentSessionsList, b as AgentCallOptions, e as AgentResult } from '../types-BSbvztCi.js';
|
|
4
|
+
export { O as SessionExpiredError, Q as clearAgentSessions } from '../types-BSbvztCi.js';
|
|
5
5
|
import 'zod';
|
|
6
6
|
import 'h3';
|
|
7
7
|
import 'ky';
|
|
@@ -69,9 +69,12 @@ declare function runScheduledFunction(definition: unknown, invocation: ScheduleI
|
|
|
69
69
|
* @internal — exported via `@trayai/helix-sdk/internal` only.
|
|
70
70
|
*/
|
|
71
71
|
/** Caller identity for user-scoped agents — the dev route forwards
|
|
72
|
-
`x-tray-user-id`
|
|
72
|
+
`x-tray-user-id` / `-email` / `-name` here, mirroring
|
|
73
|
+
`readInvocationContext` in dev. */
|
|
73
74
|
interface StandaloneIdentity {
|
|
74
75
|
userId?: string | null;
|
|
76
|
+
userEmail?: string | null;
|
|
77
|
+
userName?: string | null;
|
|
75
78
|
}
|
|
76
79
|
/** Invoke an agent outside a defineFunction execution. */
|
|
77
80
|
declare function runAgentStandalone(name: string, options: AgentCallOptions, identity?: StandaloneIdentity): Promise<AgentResult>;
|
|
@@ -314,4 +317,4 @@ declare function getAdditionalRegionProfiles(): RegionProfile[];
|
|
|
314
317
|
/** Test helper: drop non-builtin profiles and restore the built-in regions. */
|
|
315
318
|
declare function resetRegionRegistryForTests(): void;
|
|
316
319
|
|
|
317
|
-
export { AgentCallerError, CONFIG_BRIDGE_CHANNEL, DEV_TOKEN_BRIDGE_CHANNEL, type RegionProfile, type ScheduleInvocation, ScheduleInvocationError, SdkError, assertValidPath, clearActiveConfig, clearAgentRegistry, contentFilePath, getActiveConfig, getAdditionalRegionProfiles, getAgentDefinition, getRegionProfile, isKnownRegion, isSdkError, listAgentSessionsStandalone, listAgents, listExposedRegionNames, listRegionNames, metaFilePath, parseExposedRegionName, registerRegionProfile, requireRegionProfile, resetRegionRegistryForTests, resolveForcedRegion, runAgentStandalone, runScheduledFunction, setActiveConfig, setAgentBaseDir, setAgentInstructions, setForcedRegion };
|
|
320
|
+
export { AgentCallerError, CONFIG_BRIDGE_CHANNEL, DEV_TOKEN_BRIDGE_CHANNEL, type RegionProfile, type ScheduleInvocation, ScheduleInvocationError, SdkError, type StandaloneIdentity, assertValidPath, clearActiveConfig, clearAgentRegistry, contentFilePath, getActiveConfig, getAdditionalRegionProfiles, getAgentDefinition, getRegionProfile, isKnownRegion, isSdkError, listAgentSessionsStandalone, listAgents, listExposedRegionNames, listRegionNames, metaFilePath, parseExposedRegionName, registerRegionProfile, requireRegionProfile, resetRegionRegistryForTests, resolveForcedRegion, runAgentStandalone, runScheduledFunction, setActiveConfig, setAgentBaseDir, setAgentInstructions, setForcedRegion };
|
package/dist/internal/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{$ as
|
|
1
|
+
import{$ as Ae,O as C,S as fe,T as me,U as de,V as ge,W as pe,X as he,a as J,aa as Se,b as V,c as q,ca as l,d as R,e as z,f as g,g as P,ga as v,h as F,i as N,j as p,k as O,l as k,m as j,o as A,p as M,q as S,r as x,s as y,t as le,u as ce,v as ue,w as I,x as E}from"../chunk-GMEVZH35.js";import{a as h}from"../chunk-WUCX7RZO.js";import{c as G,d as D,g as Q,h as W,i as X,j as Y,k as Z,l as ee,m as te,n as re,o as oe,p as ne,q as se,r as ie,s as ae}from"../chunk-LKZKDHYO.js";import{randomUUID as xe}from"crypto";import{SpanStatusCode as H,SpanKind as ye}from"@opentelemetry/api";var s=class extends Error{constructor(e){super(`runScheduledFunction: ${e}`),this.name="ScheduleInvocationError"}};async function Ie(t,e){if(typeof e!="object"||e===null)throw new s("`invocation` must be an object");let{schedulePath:r}=e;if(typeof r!="string"||r.length===0)throw new s("`schedulePath` must be a non-empty string");if(typeof e.isManual!="boolean")throw new s("`isManual` must be a boolean");if(!v(t))throw new s(`default export of "${r}" is not a defineSchedule definition`);let b=L("scheduledAt",e.scheduledAt),c=L("firedAt",e.firedAt),u=D(),i=u.executionId??xe(),f=u.deploymentId??null,K=Date.now(),$=new Date().toISOString(),U=M(),_=A();p();let a={hasDb:!1,hasExternal:!1,hasAuth:!1,hasAi:!1,hasError:!1},m=!1,d=null;try{await P.run(a,()=>g.run(i,()=>k.startActiveSpan("schedule",{root:!0,kind:ye.SERVER,attributes:{method:"SCHEDULE",route:r,executionId:i,...f?{deploymentId:f}:{}}},async n=>{let B={type:"schedule",scheduledAt:b,firedAt:c,isManual:e.isManual},w={http:S(),db:o=>x(o),kv:()=>y(),files:()=>I(),callFunctionAsync:E(),ai:C(),agent:o=>l(o),log:_,config:U,state:{},executionId:i,deploymentId:f,traceId:n.spanContext().traceId,parentExecutionId:null,trigger:B};N(n,"input",{scheduledAt:e.scheduledAt,firedAt:e.firedAt,isManual:e.isManual});try{await h.run(w,()=>t.handler(w))}catch(o){throw m=!0,d=o instanceof Error?o.message:String(o),F("hasError"),o}finally{n.setAttribute("hasAuth",a.hasAuth),n.setAttribute("hasAi",a.hasAi),n.setAttribute("hasExternal",a.hasExternal),n.setAttribute("hasDb",a.hasDb),n.setAttribute("status",m?"error":"success");let o=m||a.hasError;n.setStatus({code:o?H.ERROR:H.OK,...d?{message:d}:{}}),n.end()}})))}finally{j({executionId:i,deploymentId:f,triggerType:"schedule",routeOrJob:r,startedAt:$,startMs:K,errored:m,errorMessage:d,userId:null,flags:a}),await O()}}function L(t,e){if(typeof e!="string"||e.length===0)throw new s(`\`${t}\` must be a timestamp string; got ${JSON.stringify(e)}`);let r=new Date(e);if(Number.isNaN(r.getTime()))throw new s(`\`${t}\` must be a Date-parseable timestamp; got ${JSON.stringify(e)}`);return r}function T(t,e){p();let r=t.userId||null,b=R(),c=crypto.randomUUID(),u={http:S(),db:i=>x(i),kv:()=>y(),files:()=>I(),callFunctionAsync:E(),ai:C(),agent:i=>l(i),log:A(),config:b.config??{},state:{},executionId:c,deploymentId:null,traceId:"",parentExecutionId:null,userId:r,identity:r!==null?{user:{id:r,email:t.userEmail||null,name:t.userName||null}}:null};return g.run(c,()=>h.run(u,e))}async function Ee(t,e,r={}){return T(r,()=>l(t).generate(e))}async function Ce(t,e){return T({userId:e.userId},()=>l(t).sessions({...e.first!==void 0?{first:e.first}:{},...e.cursor!==void 0?{cursor:e.cursor}:{}}))}export{fe as AgentCallerError,J as CONFIG_BRIDGE_CHANNEL,V as DEV_TOKEN_BRIDGE_CHANNEL,s as ScheduleInvocationError,ie as SdkError,Ae as SessionExpiredError,le as assertValidPath,z as clearActiveConfig,he as clearAgentRegistry,Se as clearAgentSessions,ce as contentFilePath,R as getActiveConfig,ne as getAdditionalRegionProfiles,ge as getAgentDefinition,X as getRegionProfile,W as isKnownRegion,ae as isSdkError,Ce as listAgentSessionsStandalone,pe as listAgents,ee as listExposedRegionNames,Z as listRegionNames,ue as metaFilePath,te as parseExposedRegionName,Q as registerRegionProfile,Y as requireRegionProfile,se as resetRegionRegistryForTests,oe as resolveForcedRegion,Ee as runAgentStandalone,Ie as runScheduledFunction,q as setActiveConfig,me as setAgentBaseDir,de as setAgentInstructions,re as setForcedRegion,G as setSdkConfig};
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
|
-
import { P as PlatformContext } from '../types-
|
|
1
|
+
import { P as PlatformContext } from '../types-BSbvztCi.js';
|
|
2
2
|
import 'h3';
|
|
3
3
|
import 'ky';
|
|
4
4
|
import 'zod';
|
|
5
5
|
import 'ai';
|
|
6
6
|
import '@ai-sdk/provider';
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Mock shape accepted by `runWithContext`: any subset of `PlatformContext`,
|
|
10
|
+
* except that `identity.user.email` / `identity.user.name` may be omitted
|
|
11
|
+
* (they default to `null`, as in a real context where the platform has no
|
|
12
|
+
* value). Extra keys on `identity.user` pass through untouched.
|
|
13
|
+
*/
|
|
14
|
+
type MockContext = Omit<Partial<PlatformContext>, "identity"> & {
|
|
15
|
+
identity?: {
|
|
16
|
+
user: {
|
|
17
|
+
id: string;
|
|
18
|
+
email?: string | null;
|
|
19
|
+
name?: string | null;
|
|
20
|
+
};
|
|
21
|
+
} | null;
|
|
22
|
+
};
|
|
8
23
|
/**
|
|
9
24
|
* Run code within a mock PlatformContext — for unit testing shared code that
|
|
10
25
|
* calls getContext(). Unset core fields throw on access via Proxy, as does
|
|
@@ -12,6 +27,6 @@ import '@ai-sdk/provider';
|
|
|
12
27
|
* optional fields (request surface, trigger) return undefined, as in a real
|
|
13
28
|
* execution of a kind that doesn't carry them.
|
|
14
29
|
*/
|
|
15
|
-
declare function runWithContext<T>(partial:
|
|
30
|
+
declare function runWithContext<T>(partial: MockContext, fn: () => T | Promise<T>): Promise<T>;
|
|
16
31
|
|
|
17
|
-
export { runWithContext };
|
|
32
|
+
export { type MockContext, runWithContext };
|
package/dist/testing/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as
|
|
1
|
+
import{a as l}from"../chunk-WUCX7RZO.js";var s={http:!0,db:!0,kv:!0,files:!0,callFunctionAsync:!0,ai:!0,agent:!0,log:!0,config:!0,state:!0,executionId:!0,deploymentId:!0,traceId:!0,parentExecutionId:!0},a={input:!0,method:!0,path:!0,headers:!0,status:!0,error:!0,request:!0,userId:!0,identity:!0,trigger:!0};function f(e){if(e===null||typeof e!="object")return e;let{user:n}=e;if(n===null||typeof n!="object")return e;let r=n;return{...e,user:{...r,email:r.email??null,name:r.name??null}}}async function c(e,n){let r=new Proxy(e,{get(o,t,u){if(typeof t=="symbol"||t==="then"||t==="toJSON")return Reflect.get(o,t,u);if(t in o){let i=Reflect.get(o,t,u);return t==="identity"?f(i):i}if(!(t in a))throw t in s?new Error(`Accessed unset context field "${String(t)}" in test. Provide it via runWithContext({ ${String(t)}: ... }, fn).`):new Error(`Accessed unknown context field "${String(t)}" in test \u2014 not a PlatformContext member.`)}});return l.run(r,n)}export{c as runWithContext};
|
|
@@ -538,14 +538,18 @@ interface TrayContext<T = Record<string, unknown>> extends ContextCore {
|
|
|
538
538
|
request: H3Event;
|
|
539
539
|
userId: string | null;
|
|
540
540
|
/**
|
|
541
|
-
*
|
|
542
|
-
*
|
|
543
|
-
*
|
|
544
|
-
*
|
|
541
|
+
* User identity context (spec 15). `id`, `email` and `name` are populated
|
|
542
|
+
* for HTTP executions by logged-in users and project API tokens; `email`
|
|
543
|
+
* and `name` are null when the platform did not supply them (for example
|
|
544
|
+
* bundles built before they were carried). Groups, roles and org details
|
|
545
|
+
* are still deferred. The whole object is null when no user is known
|
|
546
|
+
* (schedules, `ctx.callFunctionAsync` runs, anonymous callers).
|
|
545
547
|
*/
|
|
546
548
|
identity: {
|
|
547
549
|
user: {
|
|
548
550
|
id: string;
|
|
551
|
+
email: string | null;
|
|
552
|
+
name: string | null;
|
|
549
553
|
};
|
|
550
554
|
} | null;
|
|
551
555
|
}
|
|
@@ -596,6 +600,8 @@ interface PlatformContext extends ContextCore {
|
|
|
596
600
|
identity?: {
|
|
597
601
|
user: {
|
|
598
602
|
id: string;
|
|
603
|
+
email: string | null;
|
|
604
|
+
name: string | null;
|
|
599
605
|
};
|
|
600
606
|
} | null;
|
|
601
607
|
trigger?: ScheduleTrigger;
|
package/package.json
CHANGED
package/dist/chunk-JKFMPHA4.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var b="X-Helix-Project-Execution-Token",R="X-Tray-Token",q={mode:"dev",deploymentId:null},k={...q},p={};function te(e){let{internalJwt:r,helixExecutionJwt:t,devToken:n,...i}=e;"internalJwt"in e&&(p.internalJwt=r),"helixExecutionJwt"in e&&(p.helixExecutionJwt=t),"devToken"in e&&(p.devToken=n),k={...k,...i}}function ne(){return k}function S(){return p.internalJwt}function P(){return p.helixExecutionJwt}function I(){return p.devToken}var O=new Set(["us1","eu1","ap1","ap2"]),s=new Map,h={name:"us1",exposedName:"us1",displayName:"us1",hosts:{api:"https://api.tray.io",broker:"https://api.tray.io/private/v1/code",ingest:"https://api.tray.io/private/v1/helix/otlp",weaver:"https://weaver.tray.io",app:"https://app.tray.io",projectHost:"helix-app.ai",dashboard:"https://app.helix.tray.ai",auth:"https://auth.tray.io"},login:{storePrefix:"PROD",appUrl:"https://app.tray.io",cookieName:"prod_tray_lid",cookieDomain:"tray.io"}},v={name:"eu1",exposedName:"eu1",displayName:"eu1",hosts:{api:"https://api.eu1.tray.io",broker:"https://api.eu1.tray.io/private/v1/code",ingest:"https://api.eu1.tray.io/private/v1/helix/otlp",weaver:"https://weaver.eu1.tray.io",app:"https://app.eu1.tray.io",projectHost:"eu1.helix-app.ai",dashboard:"https://app.helix.eu1.tray.ai",auth:"https://auth.eu1.tray.io"},login:{storePrefix:"EU1",appUrl:"https://app.eu1.tray.io",cookieName:"prod_tray_lid_eu",cookieDomain:"tray.io"}},x={name:"ap1",exposedName:"ap1",displayName:"ap1",hosts:{api:"https://api.ap1.tray.io",broker:"https://api.ap1.tray.io/private/v1/code",ingest:"https://api.ap1.tray.io/private/v1/helix/otlp",weaver:"https://weaver.ap1.tray.io",app:"https://app.ap1.tray.io",projectHost:"ap1.helix-app.ai",dashboard:"https://app.helix.ap1.tray.ai",auth:"https://auth.ap1.tray.io"},login:{storePrefix:"AP1",appUrl:"https://app.ap1.tray.io",cookieName:"prod_tray_lid_ap",cookieDomain:"tray.io"}},E={name:"ap2",exposedName:"ap2",displayName:"ap2",hosts:{api:"https://api.ap2.tray.io",broker:"https://api.ap2.tray.io/private/v1/code",ingest:"https://api.ap2.tray.io/private/v1/helix/otlp",weaver:"https://weaver.ap2.tray.io",app:"https://app.ap2.tray.io",projectHost:"ap2.helix-app.ai",dashboard:"https://app.helix.ap2.tray.ai",auth:"https://auth.ap2.tray.io"},login:{storePrefix:"AP2",appUrl:"https://app.ap2.tray.io",cookieName:"prod_tray_lid_ap2",cookieDomain:"tray.io"}};s.set(h.name,h);s.set(v.name,v);s.set(x.name,x);s.set(E.name,E);var T=["api","broker","ingest","weaver","app","projectHost","dashboard"],N=["auth"],D=["storePrefix","appUrl","cookieName","cookieDomain"];function C(e){if(!e.name||typeof e.name!="string")throw new Error("RegionProfile.name must be a non-empty string");if(!e.exposedName||typeof e.exposedName!="string")throw new Error("RegionProfile.exposedName must be a non-empty string");if(!e.displayName||typeof e.displayName!="string")throw new Error("RegionProfile.displayName must be a non-empty string");if(!e.hosts||typeof e.hosts!="object")throw new Error("RegionProfile.hosts must be an object");if(!e.login||typeof e.login!="object")throw new Error("RegionProfile.login must be an object");for(let r of T)if(typeof e.hosts[r]!="string"||!e.hosts[r])throw new Error(`RegionProfile.hosts.${r} must be a non-empty string`);for(let r of N){let t=e.hosts[r];if(t!==void 0&&(typeof t!="string"||!t))throw new Error(`RegionProfile.hosts.${r} must be a non-empty string when set`)}for(let r of D)if(typeof e.login[r]!="string"||!e.login[r])throw new Error(`RegionProfile.login.${r} must be a non-empty string`)}function j(e,r){return e.name===r.name&&e.exposedName===r.exposedName&&e.displayName===r.displayName&&T.every(t=>e.hosts[t]===r.hosts[t])&&N.every(t=>e.hosts[t]===r.hosts[t])&&D.every(t=>e.login[t]===r.login[t])}function oe(e){C(e);let r=s.get(e.name);if(r){if(j(r,e))return;throw new Error(`RegionProfile.name "${e.name}" is already registered with different values`)}for(let t of s.values())if(t.exposedName===e.exposedName)throw new Error(`RegionProfile.exposedName "${e.exposedName}" is already used by "${t.name}"`);s.set(e.name,e)}function H(e){return s.has(e)}function se(e){return s.get(e)}function m(e){let r=s.get(e);if(!r)throw new Error(`Unknown region: ${e}`);return r}function ae(){return[...s.keys()]}function de(){return[...s.values()].map(e=>e.exposedName)}function F(e){for(let r of s.values())if(r.exposedName===e)return r.name}var f=Symbol.for("@trayai/helix-sdk.forcedEnvironment");function B(e){let r=globalThis;if(e===void 0||e.trim()===""){delete r[f];return}let t=e.trim(),n=F(t);if(n){r[f]=n;return}if(H(t)){r[f]=t;return}throw new Error(`Unknown region: ${t}`)}function le(){return globalThis[f]}function ue(){return[...s.values()].filter(e=>!O.has(e.name))}function ce(){B(void 0),s.clear();for(let e of[h,v,x,E])s.set(e.name,{...e,hosts:{...e.hosts},login:{...e.login}})}var u=class e extends Error{detail;constructor(r){super(L(r)),this.name="SdkError",this.detail=r}get kind(){return this.detail.kind}static unknownAlias(r,t){return new e({kind:"unknown_alias",alias:r,available:t})}static inputValidationFailed(r){return new e({kind:"input_validation_failed",fields:r})}static outputValidationFailed(r){return new e({kind:"output_validation_failed",fields:r})}static configLoadFailed(r){return new e({kind:"config_load_failed",cause:r})}static brokerError(r,t,n,i){return new e({kind:"broker_error",status:r,message:t,body:n,code:i})}static unsupportedBodyType(r){return new e({kind:"unsupported_body_type",actualType:r})}static unsupportedScheme(r){return new e({kind:"unsupported_scheme",scheme:r})}static missingExecutionCredentials(){return new e({kind:"missing_execution_credentials"})}static missingTrayToken(){return new e({kind:"missing_tray_token"})}static dbCallFailed(r,t){return new e({kind:"db_call_failed",message:r,cause:t})}static dbQueryFailed(r){return new e({kind:"db_query_failed",message:r})}static dbInvalidParameters(r){return new e({kind:"db_invalid_parameters",message:r})}static kvKeyInvalid(r){return new e({kind:"kv_key_invalid",message:r})}static kvValueInvalid(r){return new e({kind:"kv_value_invalid",message:r})}static kvValueTooLarge(r,t){return new e({kind:"kv_value_too_large",message:r,maxBytes:t})}static kvTtlInvalid(r){return new e({kind:"kv_ttl_invalid",message:r})}static kvNotAvailable(){return new e({kind:"kv_not_available"})}static kvCallFailed(r,t,n){return new e({kind:"kv_call_failed",status:r,message:t,body:n})}static kvRequiresProvisioning(){return new e({kind:"kv_requires_provisioning"})}static filesPathInvalid(r){return new e({kind:"files_path_invalid",message:r})}static filesValueInvalid(r){return new e({kind:"files_value_invalid",message:r})}static filesValueTooLarge(r,t){return new e({kind:"files_value_too_large",message:r,maxBytes:t})}static filesNotAvailable(){return new e({kind:"files_not_available"})}static filesCallFailed(r,t,n){return new e({kind:"files_call_failed",status:r,message:t,body:n})}static filesRequiresProvisioning(){return new e({kind:"files_requires_provisioning"})}static callFunctionPathInvalid(r){return new e({kind:"call_function_path_invalid",message:r})}static callFunctionCallFailed(r,t,n){return new e({kind:"call_function_call_failed",status:r,message:t,body:n})}static callFunctionRequiresProvisioning(){return new e({kind:"call_function_requires_provisioning"})}static callFunctionNotAvailable(){return new e({kind:"call_function_not_available"})}static callFunctionMissingExecutionJwt(){return new e({kind:"call_function_missing_execution_jwt"})}static aiUnsupportedService(r,t,n){return new e({kind:"ai_unsupported_service",alias:r,service:t,supported:n})}static aiModelIdRequired(r,t){return new e({kind:"ai_model_id_required",alias:r,operation:t})}static aiModelInstanceRequired(r){return new e({kind:"ai_model_instance_required",modelId:r})}static aiProviderNotConfigured(r,t){return new e({kind:"ai_provider_not_configured",alias:r,supported:t})}static aiProviderMisconfigured(r,t,n){return new e({kind:"ai_provider_misconfigured",alias:r,service:t,message:n})}static aiForeignModelRejected(){return new e({kind:"ai_foreign_model_rejected"})}static agentSessionsFailed(r){return new e({kind:"agent_sessions_failed",message:r})}};function ge(e){return e instanceof u}function L(e){switch(e.kind){case"unknown_alias":return`Unknown auth alias "${e.alias}". Available: ${e.available.join(", ")||"(none)"}`;case"input_validation_failed":return`Input validation failed for fields: ${e.fields.join(", ")}`;case"output_validation_failed":return`Output validation failed for fields: ${e.fields.join(", ")}`;case"config_load_failed":return`Config load failed: ${e.cause}`;case"broker_error":return e.code?`broker error: ${e.status} ${e.code}: ${e.message}`:`broker error: ${e.status} ${e.message}`;case"unsupported_body_type":return`unsupported body type: ${e.actualType}`;case"unsupported_scheme":return`unsupported scheme: ${e.scheme} (only https supported)`;case"missing_execution_credentials":return"missing execution credentials: at least one of internalJwt / helixExecutionJwt must be set before an authed broker/KV call";case"missing_tray_token":return"Not logged in. Run `helix login` to authenticate before making authed HTTP calls in dev.";case"db_call_failed":return`Database call failed: ${e.message}`;case"db_query_failed":return`Database query failed: ${e.message}`;case"db_invalid_parameters":return`Invalid database parameters: ${e.message}`;case"kv_key_invalid":return`Invalid KV key: ${e.message}`;case"kv_value_invalid":return e.message;case"kv_value_too_large":return e.message;case"kv_ttl_invalid":return e.message;case"kv_not_available":return"Key-value store is not available in this environment";case"kv_call_failed":return`KV platform error: ${e.status} ${e.message}`;case"kv_requires_provisioning":return"Key-value store requires a provisioned project (run helix project set)";case"files_path_invalid":return`Invalid file path: ${e.message}`;case"files_value_invalid":return e.message;case"files_value_too_large":return e.message;case"files_not_available":return"File storage is not available in this environment";case"files_call_failed":return`Files platform error: ${e.status} ${e.message}`;case"files_requires_provisioning":return"File storage requires a provisioned project (run helix project set)";case"call_function_path_invalid":return`Invalid function path: ${e.message}`;case"call_function_call_failed":return`Async function call failed: ${e.status} ${e.message}`;case"call_function_requires_provisioning":return"callFunctionAsync requires a provisioned project (run helix project set)";case"call_function_not_available":return"callFunctionAsync is not available: no running dev server was found";case"call_function_missing_execution_jwt":return"ctx.callFunctionAsync requires a helix project-execution JWT \u2014 a legacy internalJwt-only execution cannot call it";case"ai_unsupported_service":return`Authentication alias "${e.alias}" resolves to service "${e.service}", which ctx.ai does not support. Supported AI services: ${e.supported.join(", ")}`;case"ai_model_id_required":return`ctx.ai("${e.alias}").${e.operation} requires \`model\` as a string model id. To pass a model instance, use the top-level ctx.ai.${e.operation} instead.`;case"ai_model_instance_required":return`ctx.ai.* call functions require a model instance from ctx.ai(alias), got the string "${e.modelId}". Bare model ids would route outside the credentials broker and are not supported.`;case"ai_provider_not_configured":return`No AI provider configured for authentication alias "${e.alias}". Add \`aiProviders: { "${e.alias}": "<service>" }\` to helix.config.ts (supported services: ${e.supported.join(", ")}; bedrock needs the object form with region, openai-compatible the object form with baseUrl).`;case"ai_provider_misconfigured":return`aiProviders entry for authentication alias "${e.alias}" (service "${e.service}") is incomplete: ${e.message}`;case"ai_foreign_model_rejected":return"ctx.ai.* call functions require a model instance minted by ctx.ai(alias). A model built directly against a raw @ai-sdk/* provider carries its own transport and credentials, and would bypass the credentials broker, proxy policy, and metering.";case"agent_sessions_failed":return`Agent session store error: ${e.message}`}}import{z as g}from"zod";var A="x-helix-destination-url",U="x-helix-authentication-id",J="x-helix-deployment-id",_="x-execution-id",M="x-helix-broker-error",he="route_not_found",K=new Set([A,U,J,"authorization","x-tray-token","x-helix-project-execution-token","host","content-length","connection","transfer-encoding","te","upgrade","keep-alive","expect","proxy-authorization","proxy-connection","accept-encoding","x-request-id",_]);function V(e){let r=e.toLowerCase();return K.has(r)||r.startsWith("x-tray-internal-")}var w=g.object({error:g.object({code:g.string(),message:g.string(),issues:g.array(g.unknown()).optional()})});function ve(e,r){let t=`${m(e).hosts.api}/private/v1/helix/broker/http/raw`;return r==="dev"?`${t}/dev`:t}function xe(e){if(e.mode==="lambda"){let t=S(),n=P(),i=!!(t&&t.trim().length>0),o=!!(n&&n.trim().length>0);if(!i&&!o)throw u.missingExecutionCredentials();let a={};return i&&(a[R]=t),o&&(a[b]=n),{headers:a,deploymentId:e.deploymentId??null}}let r=I();if(!r)throw u.missingTrayToken();return{headers:{Authorization:`Bearer ${r}`},deploymentId:null}}function G(e){return typeof e=="string"||e instanceof ArrayBuffer||ArrayBuffer.isView(e)||typeof Blob<"u"&&e instanceof Blob||typeof FormData<"u"&&e instanceof FormData||e instanceof URLSearchParams||typeof ReadableStream<"u"&&e instanceof ReadableStream}function Ee(e){let r=new URL(e.url);if(r.protocol!=="https:")throw u.unsupportedScheme(r.protocol.replace(/:$/,""));if(e.query!==void 0)if(e.query instanceof URLSearchParams)for(let[l,d]of e.query.entries())r.searchParams.append(l,d);else for(let[l,d]of Object.entries(e.query))for(let $ of Array.isArray(d)?d:[d])r.searchParams.append(l,$);let t;e.headers===void 0?t=[]:e.headers instanceof Headers?t=Array.from(e.headers.entries()):Array.isArray(e.headers)?t=e.headers:t=Object.entries(e.headers);let n=t.filter(([l])=>!V(l)),i=e.body!==void 0&&e.body!==null,o,a,c=!1;return i&&(G(e.body)?(o=e.body,c=typeof ReadableStream<"u"&&e.body instanceof ReadableStream):(o=JSON.stringify(e.body),n.some(([d])=>d.toLowerCase()==="content-type")||(a="application/json"))),{authenticationId:e.authenticationId,method:e.method.toUpperCase(),destinationUrl:r.toString(),headers:n,body:o,isStreamBody:c,defaultContentType:a}}async function X(e,r){let t=await e.text(),n=t,i=t||r;try{n=JSON.parse(t);let o=w.safeParse(n);o.success&&(i=o.data.error.message)}catch{}return{status:e.status,code:r,message:i,body:n}}var Y=6e4;function z(e){return e.includes("json")}function W(e){return e.startsWith("text/")||e.includes("xml")||e.includes("urlencoded")||e.includes("javascript")||e.includes("ecmascript")}function Q(e,r){if(e.byteLength===0)return;let t=r.toLowerCase();if(z(t)){let n=new TextDecoder("utf-8").decode(e);try{return JSON.parse(n)}catch{return n}}return W(t)?new TextDecoder("utf-8").decode(e):e}function Z(e){let r={};for(let[t,n]of e.entries())r[t.toLowerCase()]=n;return r}async function we(e){let{request:r}=e,t=new Headers;for(let[l,d]of r.headers)t.append(l,d);r.defaultContentType&&!t.has("content-type")&&t.set("content-type",r.defaultContentType),t.set(A,r.destinationUrl),t.set(U,r.authenticationId);for(let[l,d]of Object.entries(e.credentialHeaders))t.set(l,d);e.executionId&&t.set(_,e.executionId);let n={method:r.method,headers:t,redirect:"manual",signal:AbortSignal.timeout(e.timeoutMs??Y)};r.body!==void 0&&(n.body=r.body,r.isStreamBody&&(n.duplex="half"));let i=await fetch(e.proxyUrl,n),o=i.headers.get(M);if(o!==null)return{kind:"brokerError",...await X(i,o)};let a=new Uint8Array(await i.arrayBuffer()),c=i.headers.get("content-type")??"";return{kind:"upstream",response:{status:i.status,headers:Z(i.headers),body:Q(a,c)}}}import{z as y}from"zod";var ee=3e4;function Te(e){let r=new URL(e);if(r.protocol!=="https:")throw u.unsupportedScheme(r.protocol.replace(/:$/,""))}function Ne(e,r){let t=`${m(e).hosts.api}/private/v1/helix/broker/s3/sign`;return r==="dev"?`${t}/dev`:t}var re=y.object({url:y.string(),method:y.string(),expiresAt:y.string()});async function De(e){let r=new Headers({"content-type":"application/json"});for(let[a,c]of Object.entries(e.credentialHeaders))r.set(a,c);e.executionId&&r.set(_,e.executionId);let t=await fetch(e.signUrl,{method:"POST",headers:r,body:JSON.stringify(e.body),redirect:"manual",signal:AbortSignal.timeout(e.timeoutMs??ee)}),n=await t.text(),i=n;try{i=JSON.parse(n)}catch{}if(t.ok){let a=re.safeParse(i);return a.success?{kind:"signed",result:a.data}:{kind:"brokerError",status:t.status,message:"malformed s3-sign response from credential broker",body:i}}let o=w.safeParse(i);return o.success?{kind:"brokerError",status:t.status,code:o.data.error.code,message:o.data.error.message,body:i}:{kind:"brokerError",status:t.status,message:n||`s3-sign request failed with status ${t.status}`,body:i}}export{b as a,R as b,te as c,ne as d,S as e,P as f,oe as g,H as h,se as i,m as j,ae as k,de as l,F as m,B as n,le as o,ue as p,ce as q,u as r,ge as s,A as t,U as u,J as v,_ as w,M as x,he as y,V as z,w as A,ve as B,xe as C,Ee as D,X as E,Y as F,we as G,Te as H,Ne as I,De as J};
|