@noodleseed/one 0.132.2 → 0.134.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/dist/commands/author-loop.d.ts.map +1 -1
- package/dist/commands/author-loop.js +3 -3
- package/dist/commands/author-loop.js.map +1 -1
- package/dist/commands/devtools.js +1 -1
- package/dist/commands/devtools.js.map +1 -1
- package/dist/commands/local-readiness.d.ts +2 -2
- package/dist/commands/local-readiness.d.ts.map +1 -1
- package/dist/commands/local-readiness.js +15 -7
- package/dist/commands/local-readiness.js.map +1 -1
- package/dist/dev-local-runtime.d.ts +33 -0
- package/dist/dev-local-runtime.d.ts.map +1 -0
- package/dist/dev-local-runtime.js +53 -0
- package/dist/dev-local-runtime.js.map +1 -0
- package/dist/dev.d.ts +4 -0
- package/dist/dev.d.ts.map +1 -1
- package/dist/dev.js +109 -31
- package/dist/dev.js.map +1 -1
- package/dist/devtools-harness.js +5 -3
- package/dist/devtools-harness.js.map +1 -1
- package/dist/devtools-preview.d.ts +2 -0
- package/dist/devtools-preview.d.ts.map +1 -1
- package/dist/devtools-preview.js +15 -3
- package/dist/devtools-preview.js.map +1 -1
- package/dist/devtools-rpc-forwarder.js +1 -1
- package/dist/devtools-rpc-forwarder.js.map +1 -1
- package/dist/preview-session.d.ts.map +1 -1
- package/dist/preview-session.js +1 -0
- package/dist/preview-session.js.map +1 -1
- package/dist/react-widget-build.d.ts +4 -0
- package/dist/react-widget-build.d.ts.map +1 -1
- package/dist/react-widget-build.js +9 -0
- package/dist/react-widget-build.js.map +1 -1
- package/node_modules/@noodle-borg/admission-limits/dist/client-address.d.ts +7 -0
- package/node_modules/@noodle-borg/admission-limits/dist/counter-store.d.ts +71 -0
- package/node_modules/@noodle-borg/admission-limits/dist/envelope.d.ts +67 -0
- package/node_modules/@noodle-borg/admission-limits/dist/in-memory-counter-store.d.ts +15 -0
- package/node_modules/@noodle-borg/admission-limits/dist/portable.d.ts +6 -0
- package/node_modules/@noodle-borg/admission-limits/dist/portable.js +6 -0
- package/node_modules/@noodle-borg/admission-limits/package.json +8 -0
- package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js +6 -6
- package/node_modules/@noodle-borg/agent-kit/dist/skill-authoring-refs.js +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-embedded-assistant-ref.js +4 -1
- package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
- package/node_modules/@noodle-borg/assistant-gateway/dist/artifact-projection.d.ts +21 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-context.d.ts +25 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-customer-issuer.d.ts +3 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-customer-routing.d.ts +19 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-guide.d.ts +39 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-interaction-state.d.ts +181 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-interactive.d.ts +99 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-interactive.js +1 -1
- package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-presentation.d.ts +35 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-sensitive-values.d.ts +3 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-store.d.ts +226 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-store.js +1 -1
- package/node_modules/@noodle-borg/assistant-gateway/dist/elevation-store.d.ts +70 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/elevation.d.ts +68 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/embed-script.d.ts +24 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/embed-store.d.ts +73 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/in-memory-elevation-store.d.ts +21 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/in-memory-embed-store.d.ts +28 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/portable.d.ts +24 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/public-session.d.ts +56 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/public-surface.d.ts +21 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/public-surface.js +2 -1
- package/node_modules/@noodle-borg/assistant-gateway/dist/public-turn.d.ts +44 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/session-resume.d.ts +22 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/surface-budget.d.ts +16 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/surface-budget.js +1 -1
- package/node_modules/@noodle-borg/assistant-gateway/dist/tenant-ref.d.ts +13 -0
- package/node_modules/@noodle-borg/authoring/dist/assistant.d.ts +9 -2
- package/node_modules/@noodle-borg/authoring/dist/assistant.js +8 -2
- package/node_modules/@noodle-borg/authoring/dist/connectors.d.ts +3 -1
- package/node_modules/@noodle-borg/authoring/dist/connectors.js +5 -1
- package/node_modules/@noodle-borg/authoring/dist/server.d.ts +2 -1
- package/node_modules/@noodle-borg/authoring/dist/server.js +4 -1
- package/node_modules/@noodle-borg/compiler/dist/artifact/assemble.js +1 -1
- package/node_modules/@noodle-borg/compiler/dist/artifact/config.js +25 -20
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.d.ts +16 -12
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.js +18 -13
- package/node_modules/@noodle-borg/connector-defs/dist/compile-http.js +2 -0
- package/node_modules/@noodle-borg/connector-defs/dist/schema.d.ts +3 -3
- package/node_modules/@noodle-borg/connector-defs/dist/schema.js +6 -1
- package/node_modules/@noodle-borg/connector-http/dist/http-connector.js +31 -8
- package/node_modules/@noodle-borg/protocol/dist/mapping.js +8 -0
- package/node_modules/@noodle-borg/runtime/dist/index.d.ts +1 -0
- package/node_modules/@noodle-borg/runtime/dist/index.js +1 -0
- package/node_modules/@noodle-borg/runtime/dist/managed-origins.d.ts +11 -0
- package/node_modules/@noodle-borg/runtime/dist/managed-origins.js +105 -0
- package/node_modules/@noodle-borg/service/dist/local-options.d.ts +9 -0
- package/node_modules/@noodle-borg/service/dist/registry-compile.js +12 -12
- package/node_modules/@noodle-borg/service/dist/routes/assistant-agent.js +14 -3
- package/node_modules/@noodle-borg/service/dist/routes/assistant-embeds.js +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/assistant-public-session.js +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/assistant-public-turn.js +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/assistant.js +1 -1
- package/node_modules/@noodle-borg/service/dist/serve-local.js +2 -3
- package/node_modules/@noodle-borg/service/package.json +1 -1
- package/node_modules/@noodleseed/assistant/README.md +4 -1
- package/package.json +5 -3
- package/node_modules/@noodle-borg/admission-limits/dist/index.js +0 -15
- package/node_modules/@noodle-borg/admission-limits/dist/postgres-counter-store.js +0 -68
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { AdmissionEnvelope, DailyCounterStore } from '@noodle-borg/admission-limits/portable';
|
|
2
|
+
import type { AssistantTurnConsumption } from './assistant-store.js';
|
|
3
|
+
import type { PublicEmbedStore } from './embed-store.js';
|
|
4
|
+
/**
|
|
5
|
+
* Whether an anonymous visitor's next turn runs.
|
|
6
|
+
*
|
|
7
|
+
* Transport-free for the same reason {@link ./public-session.ts} is: the decision about who gets to spend
|
|
8
|
+
* a customer's model budget should be provable without standing up a server. The service adapts it.
|
|
9
|
+
*
|
|
10
|
+
* The envelope arrives per call rather than being snapshotted onto the session at mint time, and that is
|
|
11
|
+
* load-bearing: `noodle assistant budget set --turns-per-day 0` must stop conversations already under
|
|
12
|
+
* way, which is precisely the case an operator reaches for the kill switch to stop. Re-reading it each
|
|
13
|
+
* turn makes the switch fall out of the ordinary path instead of needing a second mechanism.
|
|
14
|
+
*/
|
|
15
|
+
export interface PublicTurnPorts {
|
|
16
|
+
readonly counters: DailyCounterStore;
|
|
17
|
+
/** Re-read per turn: it carries the operator's live budget, and whether the surface still exists. */
|
|
18
|
+
readonly embeds: Pick<PublicEmbedStore, 'lookup'>;
|
|
19
|
+
/** Spend one of this session's turns, atomically (admission tier 1). */
|
|
20
|
+
consumeTurn(id: string, limit: number): Promise<AssistantTurnConsumption>;
|
|
21
|
+
now(): Date;
|
|
22
|
+
}
|
|
23
|
+
export interface PublicTurnRequest {
|
|
24
|
+
readonly sessionId: string;
|
|
25
|
+
/** The surface the session was admitted through; daily spend is charged against it. */
|
|
26
|
+
readonly publicEmbedId: string;
|
|
27
|
+
readonly message: string;
|
|
28
|
+
/**
|
|
29
|
+
* The visitor's hashed address bucket (admission tier 3), or absent when ingress could not be parsed.
|
|
30
|
+
* A raw address must never reach this decision, a counter key, or an audit payload.
|
|
31
|
+
*/
|
|
32
|
+
readonly addressBucket?: string | undefined;
|
|
33
|
+
}
|
|
34
|
+
export type PublicTurnResult = {
|
|
35
|
+
readonly ok: true;
|
|
36
|
+
readonly turnCount: number;
|
|
37
|
+
} | {
|
|
38
|
+
readonly ok: false;
|
|
39
|
+
readonly status: number;
|
|
40
|
+
readonly code: string;
|
|
41
|
+
readonly message: string;
|
|
42
|
+
};
|
|
43
|
+
export declare function admitPublicTurn(request: PublicTurnRequest, defaults: AdmissionEnvelope, ports: PublicTurnPorts): Promise<PublicTurnResult>;
|
|
44
|
+
//# sourceMappingURL=public-turn.d.ts.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The post-sign-in resume decision and its platform message (issue #1177). When a spent ticket
|
|
3
|
+
* elevates a session, the service may run one assistant turn so the model re-attempts the
|
|
4
|
+
* intercepted intent under the new principal — the visitor signed in to get an answer, and the
|
|
5
|
+
* panel's first content should be that answer, not silence. Transport-free like the elevation
|
|
6
|
+
* decision; `packages/service` adapts.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Whether a successful elevation arms the one-shot resume. ON by default — the demo-magic case is
|
|
10
|
+
* the default experience — with the exchange-side `resume: false` as the single disable knob (it
|
|
11
|
+
* lives in the integrator's own session endpoint, the code that spends the ticket).
|
|
12
|
+
*/
|
|
13
|
+
export declare function shouldAutoResume(override: boolean | undefined): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* The `[platform]` message that drives the resume turn, persisted to history as a user-role
|
|
16
|
+
* message like the interaction-resolution narration. It must countermand the interception's own
|
|
17
|
+
* guidance ("ask them to sign in, then offer to try again") — the sign-in already happened, and
|
|
18
|
+
* asking the visitor to repeat themselves is the silence this feature removes. Arguments are not
|
|
19
|
+
* replayed: the model re-derives them from history under the new principal.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resumeTurnMessage(tool: string): string;
|
|
22
|
+
//# sourceMappingURL=session-resume.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type AdmissionEnvelope } from '@noodle-borg/admission-limits/portable';
|
|
2
|
+
import type { PublicEmbedRecord } from './embed-store.js';
|
|
3
|
+
/**
|
|
4
|
+
* One surface's daily budget, resolved from the operator's override and the deployment's defaults.
|
|
5
|
+
*
|
|
6
|
+
* Per surface rather than per service, because the question a customer actually asks is "does capping
|
|
7
|
+
* my marketing bot throttle my in-app assistant" — and the answer has to be an obvious no. The override
|
|
8
|
+
* lives on the embed row, which `ensure` never overwrites, so a redeploy cannot silently reset a kill
|
|
9
|
+
* switch someone reached for.
|
|
10
|
+
*
|
|
11
|
+
* Routed through `clamp` rather than used directly: the structural maximum is not negotiable by an
|
|
12
|
+
* operator any more than by app code, so an over-eager `--turns-per-day 999999999` degrades to the
|
|
13
|
+
* ceiling instead of becoming the ceiling. Zero survives clamping and is the kill switch.
|
|
14
|
+
*/
|
|
15
|
+
export declare function surfaceEnvelope(base: AdmissionEnvelope, embed: Pick<PublicEmbedRecord, 'turnsPerDay' | 'mintsPerDay'>): AdmissionEnvelope;
|
|
16
|
+
//# sourceMappingURL=surface-budget.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The tenant coordinate an assistant session is bound to.
|
|
3
|
+
*
|
|
4
|
+
* Structurally re-declared rather than imported: `packages/service`'s `store.ts` remains the canonical
|
|
5
|
+
* definition, but the gateway must not depend on the hosted service (the dependency runs the other way).
|
|
6
|
+
* The two shapes are identical by contract — widen them together.
|
|
7
|
+
*/
|
|
8
|
+
export interface TenantRef {
|
|
9
|
+
readonly org: string;
|
|
10
|
+
readonly app: string;
|
|
11
|
+
readonly env: string;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=tenant-ref.d.ts.map
|
|
@@ -143,6 +143,7 @@ export type AssistantSurfaceMode = 'authenticated' | 'public' | 'mixed';
|
|
|
143
143
|
export interface AuthenticatedWebsiteAccess {
|
|
144
144
|
readonly mode: 'authenticated';
|
|
145
145
|
readonly origins: readonly string[];
|
|
146
|
+
readonly instructions?: string;
|
|
146
147
|
/** Allowlist of verified session claims; undeclared claims are dropped at session exchange. */
|
|
147
148
|
readonly sessionClaims?: Readonly<Record<string, SessionClaimDeclaration>>;
|
|
148
149
|
readonly capabilities?: readonly CapabilityRef[];
|
|
@@ -151,16 +152,21 @@ export interface PublicWebsiteAccess {
|
|
|
151
152
|
readonly mode: 'public' | 'mixed';
|
|
152
153
|
readonly origins: readonly string[];
|
|
153
154
|
readonly capabilities: readonly CapabilityRef[];
|
|
155
|
+
readonly instructions?: string;
|
|
154
156
|
}
|
|
155
157
|
export type AssistantAccess = AuthenticatedWebsiteAccess | PublicWebsiteAccess;
|
|
156
158
|
export interface AuthenticatedWebsiteInput {
|
|
157
|
-
readonly origins: readonly string[];
|
|
159
|
+
readonly origins: readonly (string | ConfigRef)[];
|
|
160
|
+
/** Assistant-only behavior for this exact signed-in website audience. */
|
|
161
|
+
readonly instructions?: string;
|
|
158
162
|
readonly sessionClaims?: Readonly<Record<string, SessionClaimDeclaration>>;
|
|
159
163
|
/** Optional narrowing; omitted means the signed-in surface projects the whole server. */
|
|
160
164
|
readonly capabilities?: readonly CapabilityRef[];
|
|
161
165
|
}
|
|
162
166
|
export interface PublicWebsiteInput {
|
|
163
|
-
readonly origins: readonly string[];
|
|
167
|
+
readonly origins: readonly (string | ConfigRef)[];
|
|
168
|
+
/** Assistant-only behavior for anonymous visitors on this website surface. */
|
|
169
|
+
readonly instructions?: string;
|
|
164
170
|
/**
|
|
165
171
|
* Required: on a public page this list *is* the externally reachable surface, so it must be an
|
|
166
172
|
* explicit positive choice rather than whatever the server happens to declare.
|
|
@@ -186,6 +192,7 @@ export interface EmbeddedAssistantOptions extends AssistantUiOptions {
|
|
|
186
192
|
export interface AssistantSurfaceConfig {
|
|
187
193
|
readonly mode: AssistantSurfaceMode;
|
|
188
194
|
readonly origins: readonly string[];
|
|
195
|
+
readonly instructions?: string;
|
|
189
196
|
readonly capabilities?: readonly AssistantCapability[];
|
|
190
197
|
readonly sessionClaims?: Readonly<Record<string, SessionClaimDeclaration>>;
|
|
191
198
|
}
|
|
@@ -2,7 +2,8 @@ import { serializeSecretRef, serializeVariableRef } from './config.js';
|
|
|
2
2
|
export function authenticatedWebsite(input) {
|
|
3
3
|
return {
|
|
4
4
|
mode: 'authenticated',
|
|
5
|
-
origins:
|
|
5
|
+
origins: serializeOrigins(input.origins, 'assistant.access.origins'),
|
|
6
|
+
...(input.instructions === undefined ? {} : { instructions: input.instructions }),
|
|
6
7
|
...(input.sessionClaims ? { sessionClaims: structuredClone(input.sessionClaims) } : {}),
|
|
7
8
|
...(input.capabilities ? { capabilities: [...input.capabilities] } : {}),
|
|
8
9
|
};
|
|
@@ -10,10 +11,14 @@ export function authenticatedWebsite(input) {
|
|
|
10
11
|
export function publicWebsite(input) {
|
|
11
12
|
return {
|
|
12
13
|
mode: input.signIn === true ? 'mixed' : 'public',
|
|
13
|
-
origins:
|
|
14
|
+
origins: serializeOrigins(input.origins, 'assistant.access.origins'),
|
|
14
15
|
capabilities: [...input.capabilities],
|
|
16
|
+
...(input.instructions === undefined ? {} : { instructions: input.instructions }),
|
|
15
17
|
};
|
|
16
18
|
}
|
|
19
|
+
function serializeOrigins(origins, path) {
|
|
20
|
+
return origins.map((origin, index) => typeof origin === 'string' ? origin : serializeVariableRef(origin, `${path}.${index}`));
|
|
21
|
+
}
|
|
17
22
|
export function openAICompatible(input) {
|
|
18
23
|
const baseUrl = typeof input.baseUrl === 'string'
|
|
19
24
|
? input.baseUrl
|
|
@@ -39,6 +44,7 @@ export function embeddedAssistant(input) {
|
|
|
39
44
|
surfaces: surfaces.map((surface) => ({
|
|
40
45
|
mode: surface.mode,
|
|
41
46
|
origins: [...surface.origins],
|
|
47
|
+
...(surface.instructions === undefined ? {} : { instructions: surface.instructions }),
|
|
42
48
|
...(surface.capabilities
|
|
43
49
|
? { capabilities: normalizeCapabilities(surface.capabilities) }
|
|
44
50
|
: {}),
|
|
@@ -77,8 +77,10 @@ type HttpOperationOptionsWithRefs = Omit<HttpConnectorDef['operations'][string],
|
|
|
77
77
|
readonly input?: OperationIoOptions;
|
|
78
78
|
readonly output?: OperationIoOptions;
|
|
79
79
|
};
|
|
80
|
-
export type HttpConnectorOptions = Omit<HttpConnectorDef['http'], 'baseUrl' | 'auth'> & {
|
|
80
|
+
export type HttpConnectorOptions = Omit<HttpConnectorDef['http'], 'baseUrl' | 'allowedOrigins' | 'auth'> & {
|
|
81
81
|
readonly baseUrl: string | ConfigRef | CustomerEndpointRef;
|
|
82
|
+
/** Exact literal or operator-managed origins that may receive connector requests. */
|
|
83
|
+
readonly allowedOrigins?: readonly (string | ConfigRef)[];
|
|
82
84
|
readonly auth?: HttpAuthOptions;
|
|
83
85
|
} & {
|
|
84
86
|
readonly credentialProfiles?: HttpConnectorDef['credentialProfiles'];
|
|
@@ -158,7 +158,11 @@ function normalizeHttpOptions(id, options) {
|
|
|
158
158
|
const normalized = {
|
|
159
159
|
...httpOptions,
|
|
160
160
|
baseUrl: normalizeBaseUrl(options.baseUrl, `connectors.${id}.http.baseUrl`),
|
|
161
|
-
...(options.allowedOrigins !== undefined
|
|
161
|
+
...(options.allowedOrigins !== undefined
|
|
162
|
+
? {
|
|
163
|
+
allowedOrigins: options.allowedOrigins.map((origin, index) => normalizeVariableOrString(origin, `connectors.${id}.http.allowedOrigins.${index}`)),
|
|
164
|
+
}
|
|
165
|
+
: {}),
|
|
162
166
|
...(options.auth !== undefined
|
|
163
167
|
? { auth: normalizeAuth(options.auth, `connectors.${id}.http.auth`) }
|
|
164
168
|
: {}),
|
|
@@ -4,6 +4,7 @@ import { type AgentGuideSource } from './agent-guide.js';
|
|
|
4
4
|
import type { EmbeddedAssistantConfig } from './assistant.js';
|
|
5
5
|
import { type DistributionMetadataSource, type DistributionMetadataV1 } from './distribution.js';
|
|
6
6
|
export { annotations } from './annotations.js';
|
|
7
|
+
import { type ConfigRef } from './config.js';
|
|
7
8
|
import { type ConnectorCatalogDoc, type ConnectorRef } from './connectors.js';
|
|
8
9
|
import { type ServerContextOptions } from './context.js';
|
|
9
10
|
import { type CustomerAuth } from './customer-auth.js';
|
|
@@ -77,7 +78,7 @@ export interface ServerOptions {
|
|
|
77
78
|
readonly colorScheme?: 'auto' | 'light' | 'dark';
|
|
78
79
|
};
|
|
79
80
|
readonly handoff?: {
|
|
80
|
-
readonly allowedDomains: readonly string[];
|
|
81
|
+
readonly allowedDomains: readonly (string | ConfigRef)[];
|
|
81
82
|
};
|
|
82
83
|
readonly state?: {
|
|
83
84
|
readonly handles: Readonly<Record<string, StateHandleOptions>>;
|
|
@@ -3,6 +3,7 @@ import { z } from 'zod';
|
|
|
3
3
|
import { manifestAgentGuide } from './agent-guide.js';
|
|
4
4
|
import { projectDistributionMetadata, } from './distribution.js';
|
|
5
5
|
export { annotations } from './annotations.js';
|
|
6
|
+
import { isConfigRef, serializeVariableRef } from './config.js';
|
|
6
7
|
import { toManifestConnectorRef } from './connections.js';
|
|
7
8
|
import { validateCatalog } from './connectors.js';
|
|
8
9
|
import { manifestContext } from './context.js';
|
|
@@ -210,7 +211,9 @@ class ServerBuilder {
|
|
|
210
211
|
...(this.options.handoff
|
|
211
212
|
? {
|
|
212
213
|
handoff: {
|
|
213
|
-
allowedDomains:
|
|
214
|
+
allowedDomains: this.options.handoff.allowedDomains.map((domain, index) => isConfigRef(domain)
|
|
215
|
+
? serializeVariableRef(domain, `server.handoff.allowedDomains.${index}`)
|
|
216
|
+
: domain),
|
|
214
217
|
},
|
|
215
218
|
}
|
|
216
219
|
: {}),
|
|
@@ -9,7 +9,7 @@ export function assembleRuntimeArtifact({ manifest, options, runtimeBranding, ru
|
|
|
9
9
|
...(artifactPrompts.length > 0 ? { prompts: artifactPrompts.map((p) => p.name) } : {}),
|
|
10
10
|
};
|
|
11
11
|
const connectorBindings = Object.fromEntries(Object.entries(declared).flatMap(([alias, connector]) => connector.binding === undefined ? [] : [[alias, connector.binding]]));
|
|
12
|
-
const config = artifactConfig(artifactTools, allResources, artifactPrompts, connectorBindings, artifactAmbientContext?.fulfilment);
|
|
12
|
+
const config = artifactConfig(manifest, artifactTools, allResources, artifactPrompts, connectorBindings, artifactAmbientContext?.fulfilment);
|
|
13
13
|
const artifact = {
|
|
14
14
|
artifactSchemaVersion: ARTIFACT_SCHEMA_VERSION,
|
|
15
15
|
resolution: options.catalog ? 'resolved' : 'shape-only',
|
|
@@ -1,19 +1,31 @@
|
|
|
1
|
-
export function artifactConfig(tools, resources, prompts, connectorBindings, ambientFulfilment) {
|
|
1
|
+
export function artifactConfig(manifest, tools, resources, prompts, connectorBindings, ambientFulfilment) {
|
|
2
2
|
const variables = new Set();
|
|
3
|
+
collectVariablesFromManagedOrigins(manifest, variables);
|
|
3
4
|
for (const tool of tools)
|
|
4
5
|
collectVariablesFromFulfilment(tool.fulfilment, variables);
|
|
5
6
|
for (const resource of resources)
|
|
6
7
|
collectVariablesFromFulfilment(resource.fulfilment, variables);
|
|
7
8
|
for (const prompt of prompts)
|
|
8
9
|
collectVariablesFromFulfilment(prompt.fulfilment, variables);
|
|
9
|
-
if (ambientFulfilment !== undefined)
|
|
10
|
+
if (ambientFulfilment !== undefined)
|
|
10
11
|
collectVariablesFromFulfilment(ambientFulfilment, variables);
|
|
11
|
-
|
|
12
|
-
for (const binding of Object.values(connectorBindings)) {
|
|
12
|
+
for (const binding of Object.values(connectorBindings))
|
|
13
13
|
collectVariablesFromConnectionSource(binding.connection.source, variables);
|
|
14
|
-
}
|
|
15
14
|
return variables.size > 0 ? { variables: [...variables].sort() } : undefined;
|
|
16
15
|
}
|
|
16
|
+
function collectVariablesFromManagedOrigins(manifest, out) {
|
|
17
|
+
const assistant = manifest.server.assistant;
|
|
18
|
+
const values = [
|
|
19
|
+
...(assistant?.allowedOrigins ?? []),
|
|
20
|
+
...(assistant?.surfaces?.flatMap((surface) => surface.origins) ?? []),
|
|
21
|
+
...(manifest.handoff?.allowedDomains ?? []),
|
|
22
|
+
];
|
|
23
|
+
for (const value of values) {
|
|
24
|
+
const match = /^\$\{env\.([A-Za-z0-9_]+)\}$/.exec(value);
|
|
25
|
+
if (match?.[1] !== undefined)
|
|
26
|
+
out.add(match[1]);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
17
29
|
function collectVariablesFromConnectionSource(source, out) {
|
|
18
30
|
const values = source.kind === 'clientCredentials'
|
|
19
31
|
? [source.tokenUrl, source.clientId]
|
|
@@ -51,36 +63,29 @@ function collectVariablesFromExprMap(map, out) {
|
|
|
51
63
|
}
|
|
52
64
|
function collectVariablesFromExpr(node, out) {
|
|
53
65
|
if (node.kind === 'path') {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
out.add(first.name);
|
|
58
|
-
}
|
|
59
|
-
return;
|
|
66
|
+
const first = node.segments[0];
|
|
67
|
+
if (node.root === 'env' && first?.kind === 'prop')
|
|
68
|
+
out.add(first.name);
|
|
60
69
|
}
|
|
61
|
-
if (node.kind === 'template') {
|
|
70
|
+
else if (node.kind === 'template') {
|
|
62
71
|
for (const part of node.parts) {
|
|
63
72
|
if (part.kind !== 'text')
|
|
64
73
|
collectVariablesFromExpr(part, out);
|
|
65
74
|
}
|
|
66
|
-
return;
|
|
67
75
|
}
|
|
68
|
-
if (node.kind === 'array') {
|
|
76
|
+
else if (node.kind === 'array') {
|
|
69
77
|
for (const item of node.items)
|
|
70
78
|
collectVariablesFromExpr(item, out);
|
|
71
|
-
return;
|
|
72
79
|
}
|
|
73
|
-
if (node.kind === 'object') {
|
|
80
|
+
else if (node.kind === 'object') {
|
|
74
81
|
for (const entry of node.entries)
|
|
75
82
|
collectVariablesFromExpr(entry.value, out);
|
|
76
|
-
return;
|
|
77
83
|
}
|
|
78
|
-
if (node.kind === 'coalesce') {
|
|
84
|
+
else if (node.kind === 'coalesce') {
|
|
79
85
|
collectVariablesFromExpr(node.left, out);
|
|
80
86
|
collectVariablesFromExpr(node.right, out);
|
|
81
|
-
return;
|
|
82
87
|
}
|
|
83
|
-
if (node.kind === 'function') {
|
|
88
|
+
else if (node.kind === 'function') {
|
|
84
89
|
for (const arg of node.args)
|
|
85
90
|
collectVariablesFromExpr(arg, out);
|
|
86
91
|
}
|
|
@@ -6,7 +6,7 @@ type ToolAuthorizationManifest = {
|
|
|
6
6
|
};
|
|
7
7
|
export declare const manifestV1Schema: z.ZodObject<{
|
|
8
8
|
handoff: z.ZodOptional<z.ZodObject<{
|
|
9
|
-
allowedDomains: z.ZodArray<z.ZodURL
|
|
9
|
+
allowedDomains: z.ZodArray<z.ZodUnion<readonly [z.ZodURL, z.ZodString]>>;
|
|
10
10
|
}, z.core.$strict>>;
|
|
11
11
|
state: z.ZodOptional<z.ZodObject<{
|
|
12
12
|
handles: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
@@ -331,14 +331,15 @@ export declare const manifestV1Schema: z.ZodObject<{
|
|
|
331
331
|
model: z.ZodString;
|
|
332
332
|
apiKey: z.ZodString;
|
|
333
333
|
}, z.core.$strict>;
|
|
334
|
-
allowedOrigins: z.ZodArray<z.
|
|
334
|
+
allowedOrigins: z.ZodArray<z.ZodString>;
|
|
335
335
|
surfaces: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
336
336
|
mode: z.ZodEnum<{
|
|
337
337
|
authenticated: "authenticated";
|
|
338
338
|
public: "public";
|
|
339
339
|
mixed: "mixed";
|
|
340
340
|
}>;
|
|
341
|
-
origins: z.ZodArray<z.
|
|
341
|
+
origins: z.ZodArray<z.ZodString>;
|
|
342
|
+
instructions: z.ZodOptional<z.ZodString>;
|
|
342
343
|
capabilities: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
343
344
|
kind: z.ZodEnum<{
|
|
344
345
|
tool: "tool";
|
|
@@ -498,7 +499,7 @@ export declare const manifestV1Schema: z.ZodObject<{
|
|
|
498
499
|
}, z.core.$strip>;
|
|
499
500
|
export declare const manifestV2Schema: z.ZodObject<{
|
|
500
501
|
handoff: z.ZodOptional<z.ZodObject<{
|
|
501
|
-
allowedDomains: z.ZodArray<z.ZodURL
|
|
502
|
+
allowedDomains: z.ZodArray<z.ZodUnion<readonly [z.ZodURL, z.ZodString]>>;
|
|
502
503
|
}, z.core.$strict>>;
|
|
503
504
|
state: z.ZodOptional<z.ZodObject<{
|
|
504
505
|
handles: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
@@ -781,14 +782,15 @@ export declare const manifestV2Schema: z.ZodObject<{
|
|
|
781
782
|
model: z.ZodString;
|
|
782
783
|
apiKey: z.ZodString;
|
|
783
784
|
}, z.core.$strict>;
|
|
784
|
-
allowedOrigins: z.ZodArray<z.
|
|
785
|
+
allowedOrigins: z.ZodArray<z.ZodString>;
|
|
785
786
|
surfaces: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
786
787
|
mode: z.ZodEnum<{
|
|
787
788
|
authenticated: "authenticated";
|
|
788
789
|
public: "public";
|
|
789
790
|
mixed: "mixed";
|
|
790
791
|
}>;
|
|
791
|
-
origins: z.ZodArray<z.
|
|
792
|
+
origins: z.ZodArray<z.ZodString>;
|
|
793
|
+
instructions: z.ZodOptional<z.ZodString>;
|
|
792
794
|
capabilities: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
793
795
|
kind: z.ZodEnum<{
|
|
794
796
|
tool: "tool";
|
|
@@ -1116,7 +1118,7 @@ export declare const manifestV2Schema: z.ZodObject<{
|
|
|
1116
1118
|
}, z.core.$strip>;
|
|
1117
1119
|
export declare const manifestSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
1118
1120
|
handoff: z.ZodOptional<z.ZodObject<{
|
|
1119
|
-
allowedDomains: z.ZodArray<z.ZodURL
|
|
1121
|
+
allowedDomains: z.ZodArray<z.ZodUnion<readonly [z.ZodURL, z.ZodString]>>;
|
|
1120
1122
|
}, z.core.$strict>>;
|
|
1121
1123
|
state: z.ZodOptional<z.ZodObject<{
|
|
1122
1124
|
handles: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
@@ -1441,14 +1443,15 @@ export declare const manifestSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
1441
1443
|
model: z.ZodString;
|
|
1442
1444
|
apiKey: z.ZodString;
|
|
1443
1445
|
}, z.core.$strict>;
|
|
1444
|
-
allowedOrigins: z.ZodArray<z.
|
|
1446
|
+
allowedOrigins: z.ZodArray<z.ZodString>;
|
|
1445
1447
|
surfaces: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1446
1448
|
mode: z.ZodEnum<{
|
|
1447
1449
|
authenticated: "authenticated";
|
|
1448
1450
|
public: "public";
|
|
1449
1451
|
mixed: "mixed";
|
|
1450
1452
|
}>;
|
|
1451
|
-
origins: z.ZodArray<z.
|
|
1453
|
+
origins: z.ZodArray<z.ZodString>;
|
|
1454
|
+
instructions: z.ZodOptional<z.ZodString>;
|
|
1452
1455
|
capabilities: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1453
1456
|
kind: z.ZodEnum<{
|
|
1454
1457
|
tool: "tool";
|
|
@@ -1607,7 +1610,7 @@ export declare const manifestSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
1607
1610
|
}, z.core.$strip>>>;
|
|
1608
1611
|
}, z.core.$strip>, z.ZodObject<{
|
|
1609
1612
|
handoff: z.ZodOptional<z.ZodObject<{
|
|
1610
|
-
allowedDomains: z.ZodArray<z.ZodURL
|
|
1613
|
+
allowedDomains: z.ZodArray<z.ZodUnion<readonly [z.ZodURL, z.ZodString]>>;
|
|
1611
1614
|
}, z.core.$strict>>;
|
|
1612
1615
|
state: z.ZodOptional<z.ZodObject<{
|
|
1613
1616
|
handles: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
@@ -1890,14 +1893,15 @@ export declare const manifestSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
1890
1893
|
model: z.ZodString;
|
|
1891
1894
|
apiKey: z.ZodString;
|
|
1892
1895
|
}, z.core.$strict>;
|
|
1893
|
-
allowedOrigins: z.ZodArray<z.
|
|
1896
|
+
allowedOrigins: z.ZodArray<z.ZodString>;
|
|
1894
1897
|
surfaces: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1895
1898
|
mode: z.ZodEnum<{
|
|
1896
1899
|
authenticated: "authenticated";
|
|
1897
1900
|
public: "public";
|
|
1898
1901
|
mixed: "mixed";
|
|
1899
1902
|
}>;
|
|
1900
|
-
origins: z.ZodArray<z.
|
|
1903
|
+
origins: z.ZodArray<z.ZodString>;
|
|
1904
|
+
instructions: z.ZodOptional<z.ZodString>;
|
|
1901
1905
|
capabilities: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1902
1906
|
kind: z.ZodEnum<{
|
|
1903
1907
|
tool: "tool";
|
|
@@ -135,9 +135,13 @@ const promptSchema = z.object({
|
|
|
135
135
|
});
|
|
136
136
|
const hexColorSchema = z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'must be a 6-digit hex color');
|
|
137
137
|
const httpsUrlSchema = z.url().regex(/^https:\/\//, 'must use https');
|
|
138
|
+
const managedVariableExpressionPattern = /^\$\{env\.[A-Za-z0-9_]+\}$/;
|
|
139
|
+
const managedVariableExpressionSchema = z
|
|
140
|
+
.string()
|
|
141
|
+
.regex(managedVariableExpressionPattern, 'must be an exact managed variable expression');
|
|
138
142
|
// HTTP is allowed only for loopback development origins (mirrors the host-pattern loopback
|
|
139
143
|
// exception used for connector/CSP origins); production embedding origins stay https-only.
|
|
140
|
-
const
|
|
144
|
+
const assistantOriginOrVariablePattern = /^(?:\$\{env\.[A-Za-z0-9_]+\}|https:\/\/[^/?#@\\]+|http:\/\/(?:localhost|127\.0\.0\.1|\[::1\])(?::\d+)?)$/;
|
|
141
145
|
function isCanonicalAssistantOrigin(value) {
|
|
142
146
|
try {
|
|
143
147
|
return new URL(value).origin === value;
|
|
@@ -146,10 +150,10 @@ function isCanonicalAssistantOrigin(value) {
|
|
|
146
150
|
return false;
|
|
147
151
|
}
|
|
148
152
|
}
|
|
149
|
-
const
|
|
150
|
-
.
|
|
151
|
-
.regex(
|
|
152
|
-
.refine(isCanonicalAssistantOrigin, 'must be a canonical bare origin');
|
|
153
|
+
const assistantOriginOrVariableSchema = z
|
|
154
|
+
.string()
|
|
155
|
+
.regex(assistantOriginOrVariablePattern, 'must be a canonical bare origin using https (http is allowed only for localhost/127.0.0.1/[::1] loopback development origins)')
|
|
156
|
+
.refine((value) => managedVariableExpressionPattern.test(value) || isCanonicalAssistantOrigin(value), 'must be a canonical bare origin');
|
|
153
157
|
const packagedAssetSchema = z
|
|
154
158
|
.object({
|
|
155
159
|
kind: z.literal('asset'),
|
|
@@ -330,6 +334,11 @@ const assistantCapabilitySchema = z
|
|
|
330
334
|
name: z.string().trim().min(1),
|
|
331
335
|
})
|
|
332
336
|
.strict();
|
|
337
|
+
/**
|
|
338
|
+
* Upper bound on server- and surface-level instructions. These are concise behavior primers, not
|
|
339
|
+
* documentation; the shared cap keeps prompt ownership predictable across both layers.
|
|
340
|
+
*/
|
|
341
|
+
const MAX_SERVER_INSTRUCTIONS = 4000;
|
|
333
342
|
/** Verified session claims an embedding backend may pass at exchange; undeclared keys are dropped. */
|
|
334
343
|
const sessionClaimsSchema = z.record(z.string().regex(/^[A-Za-z][A-Za-z0-9_]{0,63}$/, 'claim keys are identifier-style'), z.object({ exposeToModel: z.boolean().optional() }).strict());
|
|
335
344
|
const embeddedAssistantSchema = z
|
|
@@ -342,7 +351,7 @@ const embeddedAssistantSchema = z
|
|
|
342
351
|
apiKey: z.string().regex(/^[A-Za-z0-9_]+$/),
|
|
343
352
|
})
|
|
344
353
|
.strict(),
|
|
345
|
-
allowedOrigins: z.array(
|
|
354
|
+
allowedOrigins: z.array(assistantOriginOrVariableSchema).min(1),
|
|
346
355
|
// The front doors this assistant serves (ADR 0201, amended 2026-08-12). Absent means the pre-0201
|
|
347
356
|
// authenticated shape, so released artifacts keep their meaning; `allowedOrigins` stays the union
|
|
348
357
|
// and `sessionClaims` stays mirrored, so the service reads both unchanged. `capabilities` is the
|
|
@@ -351,7 +360,8 @@ const embeddedAssistantSchema = z
|
|
|
351
360
|
.array(z
|
|
352
361
|
.object({
|
|
353
362
|
mode: z.enum(['authenticated', 'public', 'mixed']),
|
|
354
|
-
origins: z.array(
|
|
363
|
+
origins: z.array(assistantOriginOrVariableSchema).min(1),
|
|
364
|
+
instructions: z.string().trim().min(1).max(MAX_SERVER_INSTRUCTIONS).optional(),
|
|
355
365
|
capabilities: z.array(assistantCapabilitySchema).optional(),
|
|
356
366
|
sessionClaims: sessionClaimsSchema.optional(),
|
|
357
367
|
})
|
|
@@ -423,11 +433,6 @@ const serverShellSchema = z
|
|
|
423
433
|
persistentActions: z.array(serverShellActionSchema).optional(),
|
|
424
434
|
})
|
|
425
435
|
.strict();
|
|
426
|
-
/**
|
|
427
|
-
* Upper bound on `server.instructions`. Hosts inject instructions into every session's context, so the
|
|
428
|
-
* field is for a concise usage primer (a few hundred words), not documentation.
|
|
429
|
-
*/
|
|
430
|
-
const MAX_SERVER_INSTRUCTIONS = 4000;
|
|
431
436
|
const serverContextSchema = z
|
|
432
437
|
.object({
|
|
433
438
|
defaults: z
|
|
@@ -472,7 +477,7 @@ const serverV2Schema = serverSchema.extend({
|
|
|
472
477
|
});
|
|
473
478
|
const handoffSchema = z
|
|
474
479
|
.object({
|
|
475
|
-
allowedDomains: z.array(httpsUrlSchema).min(1),
|
|
480
|
+
allowedDomains: z.array(z.union([httpsUrlSchema, managedVariableExpressionSchema])).min(1),
|
|
476
481
|
})
|
|
477
482
|
.strict();
|
|
478
483
|
const stateHandleSchema = z
|
|
@@ -22,6 +22,8 @@ export function compileHttpConnector(def, mode, errors, catalog, connectors, sec
|
|
|
22
22
|
(stringBase === undefined || isVariableExpression(stringBase) ? [] : [stringBase]);
|
|
23
23
|
if (stringBase !== undefined)
|
|
24
24
|
collectVariableExpression(stringBase, variableBindings);
|
|
25
|
+
for (const origin of allowedOrigins)
|
|
26
|
+
collectVariableExpression(origin, variableBindings);
|
|
25
27
|
if (def.http.auth !== undefined)
|
|
26
28
|
collectVariablesFromHttpAuth(def.http.auth, variableBindings);
|
|
27
29
|
if (routedBase) {
|
|
@@ -269,7 +269,7 @@ declare const httpConnectorDefSchema: z.ZodObject<{
|
|
|
269
269
|
readonly allowedHttpsHostSuffixes: readonly string[];
|
|
270
270
|
}, unknown>>;
|
|
271
271
|
}, z.core.$strict>]>;
|
|
272
|
-
allowedOrigins: z.ZodOptional<z.ZodArray<z.ZodString
|
|
272
|
+
allowedOrigins: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodString]>>>;
|
|
273
273
|
auth: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
274
274
|
kind: z.ZodLiteral<"bearer">;
|
|
275
275
|
secret: z.ZodString;
|
|
@@ -551,7 +551,7 @@ declare const connectorDefSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
551
551
|
readonly allowedHttpsHostSuffixes: readonly string[];
|
|
552
552
|
}, unknown>>;
|
|
553
553
|
}, z.core.$strict>]>;
|
|
554
|
-
allowedOrigins: z.ZodOptional<z.ZodArray<z.ZodString
|
|
554
|
+
allowedOrigins: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodString]>>>;
|
|
555
555
|
auth: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
556
556
|
kind: z.ZodLiteral<"bearer">;
|
|
557
557
|
secret: z.ZodString;
|
|
@@ -828,7 +828,7 @@ export declare const connectorFileSchema: z.ZodObject<{
|
|
|
828
828
|
readonly allowedHttpsHostSuffixes: readonly string[];
|
|
829
829
|
}, unknown>>;
|
|
830
830
|
}, z.core.$strict>]>;
|
|
831
|
-
allowedOrigins: z.ZodOptional<z.ZodArray<z.ZodString
|
|
831
|
+
allowedOrigins: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodString]>>>;
|
|
832
832
|
auth: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
833
833
|
kind: z.ZodLiteral<"bearer">;
|
|
834
834
|
secret: z.ZodString;
|
|
@@ -366,6 +366,9 @@ const computeOperationSchema = z
|
|
|
366
366
|
credentials: operationCredentialsSchema.optional(),
|
|
367
367
|
})
|
|
368
368
|
.strict();
|
|
369
|
+
const managedVariableExpressionSchema = z
|
|
370
|
+
.string()
|
|
371
|
+
.regex(/^\$\{env\.[A-Za-z0-9_]+\}$/, 'must be an exact managed variable expression');
|
|
369
372
|
const connectorIdentity = {
|
|
370
373
|
id: z.string().min(1),
|
|
371
374
|
version: z.string().min(1),
|
|
@@ -381,7 +384,9 @@ const httpConnectorDefSchema = z
|
|
|
381
384
|
http: z
|
|
382
385
|
.object({
|
|
383
386
|
baseUrl: baseUrlSchema,
|
|
384
|
-
allowedOrigins: z
|
|
387
|
+
allowedOrigins: z
|
|
388
|
+
.array(z.union([z.string().url(), managedVariableExpressionSchema]))
|
|
389
|
+
.optional(),
|
|
385
390
|
/** Connector-default auth scheme; an operation's own `auth` overrides it. */
|
|
386
391
|
auth: httpAuthSchema.optional(),
|
|
387
392
|
})
|