@noodleseed/one 0.150.0 → 0.151.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/commands/assistant-ops.d.ts.map +1 -1
  2. package/dist/commands/assistant-ops.js +4 -1
  3. package/dist/commands/assistant-ops.js.map +1 -1
  4. package/dist/commands/assistant-sponsorship-ops.d.ts +3 -0
  5. package/dist/commands/assistant-sponsorship-ops.d.ts.map +1 -0
  6. package/dist/commands/assistant-sponsorship-ops.js +170 -0
  7. package/dist/commands/assistant-sponsorship-ops.js.map +1 -0
  8. package/dist/commands/assistant-surface-ops.d.ts.map +1 -1
  9. package/dist/commands/assistant-surface-ops.js +3 -1
  10. package/dist/commands/assistant-surface-ops.js.map +1 -1
  11. package/dist/commands/intents-ops.js +1 -1
  12. package/dist/commands/intents-ops.js.map +1 -1
  13. package/node_modules/@noodle-borg/admission-limits/dist/counter-store.d.ts +11 -0
  14. package/node_modules/@noodle-borg/admission-limits/dist/in-memory-counter-store.d.ts +3 -2
  15. package/node_modules/@noodle-borg/admission-limits/dist/in-memory-counter-store.js +22 -0
  16. package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js +1 -1
  17. package/node_modules/@noodle-borg/agent-kit/dist/skill-embedded-assistant-ref.js +1 -1
  18. package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
  19. package/node_modules/@noodle-borg/assistant-gateway/dist/app-tool-call.js +6 -3
  20. package/node_modules/@noodle-borg/assistant-gateway/dist/model-error.js +6 -0
  21. package/node_modules/@noodle-borg/assistant-gateway/dist/model-request.d.ts +11 -0
  22. package/node_modules/@noodle-borg/assistant-gateway/dist/model-request.js +22 -1
  23. package/node_modules/@noodle-borg/assistant-gateway/package.json +1 -1
  24. package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-assistant.js +94 -0
  25. package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-hosted-observability.js +1 -1
  26. package/node_modules/@noodle-borg/module/dist/index.d.ts +1 -0
  27. package/node_modules/@noodle-borg/module/dist/index.js +1 -0
  28. package/node_modules/@noodle-borg/module/dist/logger.d.ts +15 -0
  29. package/node_modules/@noodle-borg/module/dist/logger.js +16 -0
  30. package/node_modules/@noodle-borg/observability/dist/assistant-app-tool-usage.js +23 -1
  31. package/node_modules/@noodle-borg/service/dist/observability-runtime.js +6 -4
  32. package/node_modules/@noodle-borg/service/dist/routes/assistant.js +26 -16
  33. package/node_modules/@noodle-borg/service/dist/routes/intent-capture.js +12 -0
  34. package/node_modules/@noodle-borg/service/dist/service.js +3 -2
  35. package/node_modules/@noodle-borg/service/package.json +1 -1
  36. package/node_modules/@noodle-borg/wire-contracts/dist/index.d.ts +1 -0
  37. package/node_modules/@noodle-borg/wire-contracts/dist/index.js +1 -0
  38. package/node_modules/@noodle-borg/wire-contracts/dist/managed-assistant-sponsorship.d.ts +297 -0
  39. package/node_modules/@noodle-borg/wire-contracts/dist/managed-assistant-sponsorship.js +94 -0
  40. package/node_modules/@noodleseed/assistant/package.json +1 -1
  41. package/package.json +2 -2
@@ -0,0 +1,16 @@
1
+ export function adaptModuleLogger(logger, base = {}) {
2
+ const fields = (extra) => ({ ...base, ...extra });
3
+ const log = (level, event, extra) => {
4
+ logger[level](event, fields(extra));
5
+ };
6
+ return {
7
+ level: 'debug',
8
+ log,
9
+ debug: (event, extra) => log('debug', event, extra),
10
+ info: (event, extra) => log('info', event, extra),
11
+ warn: (event, extra) => log('warn', event, extra),
12
+ error: (event, extra) => log('error', event, extra),
13
+ child: (extra) => adaptModuleLogger(logger, fields(extra)),
14
+ };
15
+ }
16
+ //# sourceMappingURL=logger.js.map
@@ -1,4 +1,5 @@
1
1
  import { randomUUID } from 'node:crypto';
2
+ import { captureAssistantUsage } from './assistant-usage.js';
2
3
  /** Project one apps-bridge tool call onto the shared tenant request stream. */
3
4
  export function assistantAppToolCallRequestEvent(session, input) {
4
5
  const isPublic = session.publicEmbedId !== undefined;
@@ -13,7 +14,7 @@ export function assistantAppToolCallRequestEvent(session, input) {
13
14
  surface: input.bridged ? 'webmcp' : isPublic ? 'assistant-public' : 'assistant-authenticated',
14
15
  method: 'tools/call',
15
16
  kind: 'usage',
16
- toolName: input.toolName,
17
+ ...(input.toolName === undefined ? {} : { toolName: input.toolName }),
17
18
  outcome: input.outcome === 'ok' ? 'ok' : input.outcome === 'refused' ? 'tool_error' : 'mcp_error',
18
19
  ...(input.errorKind === undefined ? {} : { errorKind: input.errorKind }),
19
20
  durationMs: Number.isFinite(input.durationMs) && input.durationMs > 0 ? input.durationMs : 0,
@@ -22,4 +23,25 @@ export function assistantAppToolCallRequestEvent(session, input) {
22
23
  details: { eventKind: 'appToolCall', bridged: input.bridged },
23
24
  };
24
25
  }
26
+ /**
27
+ * Bind one apps-bridge tool call's fixed facts, leaving the caller a recorder it can run at any
28
+ * exit. The route reaches several of them -- a budget refusal before any resolution work, an
29
+ * unprojected tool, bad arguments, a raised confirmation, a result -- and assembling the event at
30
+ * each one is how one of them ends up forgotten, which is what happened to the budget refusal.
31
+ */
32
+ export function assistantAppToolCallRecorder(input) {
33
+ const startedAt = input.clock();
34
+ return (outcome, errorKind) => {
35
+ captureAssistantUsage(input.capture, assistantAppToolCallRequestEvent(input.session, {
36
+ // Absent when the caller named no tool. That row still matters: a nameless call that
37
+ // exhausts a budget is the shape abusive traffic takes, and it is the row an operator
38
+ // watching a browser agent would miss if a missing name suppressed the event.
39
+ ...(input.toolName === undefined ? {} : { toolName: input.toolName }),
40
+ bridged: input.bridged,
41
+ outcome,
42
+ ...(errorKind === undefined ? {} : { errorKind }),
43
+ durationMs: input.clock() - startedAt,
44
+ }));
45
+ };
46
+ }
25
47
  //# sourceMappingURL=assistant-app-tool-usage.js.map
@@ -8,16 +8,17 @@ export function createObservabilityStores(options) {
8
8
  options.intentCaptureSettingsStore ?? new InMemoryIntentCaptureSettingsStore(),
9
9
  options.intentEventStore ?? new InMemoryIntentEventStore(),
10
10
  options.requestEventStore ?? new InMemoryRequestEventStore(),
11
+ new Set(options.intentCapturePreviewOrgs ?? []),
11
12
  ];
12
13
  }
13
- export async function resolveIntentMode(target, ref, settings) {
14
+ export async function resolveIntentMode(target, ref, previewOrgs, settings) {
14
15
  if (target === undefined)
15
16
  return undefined;
16
17
  const resolved = ref ??
17
18
  (target.org !== undefined && target.app !== undefined && target.environment !== undefined
18
19
  ? { org: target.org, app: target.app, env: target.environment }
19
20
  : undefined);
20
- if (resolved === undefined)
21
+ if (resolved === undefined || !previewOrgs.has(resolved.org))
21
22
  return target;
22
23
  try {
23
24
  const setting = await settings.get(resolved);
@@ -27,8 +28,8 @@ export async function resolveIntentMode(target, ref, settings) {
27
28
  return target;
28
29
  }
29
30
  }
30
- export function createIntentTargetResolver(settings) {
31
- return (target, ref) => resolveIntentMode(target, ref, settings);
31
+ export function createIntentTargetResolver(settings, previewOrgs) {
32
+ return (target, ref) => resolveIntentMode(target, ref, previewOrgs, settings);
32
33
  }
33
34
  export function createObservabilityDispatcher(deps) {
34
35
  return (req, res, url) => dispatchAnalyticsReads(req, res, url, {
@@ -49,6 +50,7 @@ export function createObservabilityDispatcher(deps) {
49
50
  requests: deps.requestEvents,
50
51
  audit: deps.audit,
51
52
  maxBody: deps.maxBody,
53
+ previewOrgs: deps.previewOrgs,
52
54
  applySecurityHeaders,
53
55
  enforceHttps,
54
56
  sendJson,
@@ -3,7 +3,7 @@ import { assistantModelFailure, assistantModelSource, assistantModelTransport, }
3
3
  import { ASSISTANT_SESSION_IDLE_MS, effectiveAssistantBrowserConfiguration, executeAssistantAppToolCall, isAssistantPageContext, isAssistantVerifiedClaims, parseAssistantContextPreferences, parseAssistantCustomerRouting, refuseBridgeToolCall, refusePublicTurn, resolveInvocationContextSnapshot, resumeTurnMessage, resumeUnavailableMessage, shouldAutoResume, surfaceBindingForOrigin, withAssistantSessionExecutionAuthority, } from '@noodle-borg/assistant-gateway/portable';
4
4
  import { canonicalizeAuthorizationClaimValues } from '@noodle-borg/auth';
5
5
  import { tenantMcpUrl } from '@noodle-borg/module';
6
- import { assistantAppToolCallRequestEvent, assistantRefusedTurnUsageRequestEvent, assistantSessionUsageRequestEvent, assistantTurnNumber, assistantTurnUsageRequestEvent, captureAssistantUsage, } from '@noodle-borg/observability';
6
+ import { assistantAppToolCallRecorder, assistantRefusedTurnUsageRequestEvent, assistantSessionUsageRequestEvent, assistantTurnNumber, assistantTurnUsageRequestEvent, captureAssistantUsage, } from '@noodle-borg/observability';
7
7
  import { mapExecutionError, mapResourceContents, mapResourcesList, mapToolOutput, mapToolsList, } from '@noodle-borg/protocol';
8
8
  import { executeResource } from '@noodle-borg/runtime';
9
9
  import { assistantMessageTurnRequestSchema, assistantResumeTurnRequestSchema, assistantSessionResponseSchema, } from '@noodle-borg/wire-contracts';
@@ -385,9 +385,21 @@ export async function handleAssistantAppRequest(req, res, deps) {
385
385
  // Answered before any resolution work, so a refused browser agent costs nothing (ADR 0220). The
386
386
  // marker is client-declared: it selects a budget, never authority, which the session below decides.
387
387
  const bridged = method === 'tools/call' && body.value.bridge === 'webmcp';
388
+ // Bound before the budget gate below, because that refusal is the one an operator watching a
389
+ // browser agent most needs to see, and answering it before any resolution work must not mean
390
+ // answering it silently. `bridged` is attribution only: it labels the row, never authority.
391
+ const record = assistantAppToolCallRecorder({
392
+ capture: deps.captureRequestEvent,
393
+ session,
394
+ ...(typeof params.name === 'string' ? { toolName: params.name } : { toolName: undefined }),
395
+ bridged,
396
+ clock: () => performance.now(),
397
+ });
388
398
  const refusal = bridged ? await refuseBridgeToolCall(deps, session) : undefined;
389
- if (refusal)
399
+ if (refusal) {
400
+ record('refused', refusal.code);
390
401
  return sendJson(res, refusal.status, { error: refusal.message, code: refusal.code });
402
+ }
391
403
  const knowledge = await resolveAssistantKnowledge(target.served);
392
404
  if (method === 'tools/list') {
393
405
  return sendJson(res, 200, mapToolsList(target.served.artifact, session.caller, {
@@ -423,25 +435,23 @@ export async function handleAssistantAppRequest(req, res, deps) {
423
435
  return sendJson(res, 200, mapResourceContents(resource.uri, resource.mimeType, execution.output, resource._meta));
424
436
  }
425
437
  if (method === 'tools/call') {
426
- if (typeof params.name !== 'string')
438
+ if (typeof params.name !== 'string') {
439
+ record('refused', 'tool_name_required');
427
440
  return sendJson(res, 400, { error: 'tool name required' });
428
- const startedAt = performance.now();
441
+ }
429
442
  const toolName = params.name;
430
- // Recorded on every exit below, including the refusals: a rejected browser-agent call is
431
- // exactly the traffic an operator watching one needs to see (ADR 0220 decision 6).
432
- const record = (outcome, errorKind) => captureAssistantUsage(deps.captureRequestEvent, assistantAppToolCallRequestEvent(session, {
433
- toolName,
434
- // Attribution only. The marker labels the row; the session decided authority above.
435
- bridged,
436
- outcome,
437
- ...(errorKind === undefined ? {} : { errorKind }),
438
- durationMs: performance.now() - startedAt,
439
- }));
440
443
  const knowledgeComponent = findAssistantKnowledgeComponent(knowledge, toolName);
441
444
  if (knowledge !== undefined && knowledgeComponent !== undefined) {
442
445
  const content = await executeAssistantKnowledgeSearch(knowledge, knowledgeComponent, params.arguments ?? {});
443
- record('ok');
444
- return sendJson(res, 200, mapToolOutput(JSON.parse(content)));
446
+ // A knowledge search reports failure in its payload rather than by throwing, so reading the
447
+ // envelope is the only way not to file a refused or failed search as a successful one.
448
+ const payload = JSON.parse(content);
449
+ const failure = isRecord(payload) && typeof payload.error === 'string' ? payload.error : undefined;
450
+ if (failure === undefined)
451
+ record('ok');
452
+ else
453
+ record(failure === 'invalid_arguments' ? 'refused' : 'failed', failure);
454
+ return sendJson(res, 200, mapToolOutput(payload));
445
455
  }
446
456
  const call = await executeAssistantAppToolCall({
447
457
  artifact: target.served.artifact,
@@ -14,6 +14,9 @@ export async function handleIntentCaptureSettings(req, res, ref, deps) {
14
14
  const identity = await authorizeTenantControl(req, res, deps.gate, deps.controlPlane, ref.org);
15
15
  if (identity === false)
16
16
  return;
17
+ if (!deps.previewOrgs.has(ref.org)) {
18
+ return sendJson(res, 403, { ok: false, error: 'intent capture preview is unavailable' });
19
+ }
17
20
  const setting = await deps.settings.get(ref);
18
21
  return sendJson(res, 200, {
19
22
  ok: true,
@@ -29,6 +32,9 @@ export async function handleIntentCaptureSettings(req, res, ref, deps) {
29
32
  const identity = await authorizeOwner(req, res, ref, deps);
30
33
  if (identity === undefined)
31
34
  return;
35
+ if (!deps.previewOrgs.has(ref.org)) {
36
+ return sendJson(res, 403, { ok: false, error: 'intent capture preview is unavailable' });
37
+ }
32
38
  const body = await readJsonBody(req, deps.maxBody);
33
39
  if (!body.ok)
34
40
  return sendJson(res, body.status, { error: body.error });
@@ -68,6 +74,9 @@ export async function handleIntentCaptureSettings(req, res, ref, deps) {
68
74
  const identity = await authorizeOwner(req, res, ref, deps);
69
75
  if (identity === undefined)
70
76
  return;
77
+ if (!deps.previewOrgs.has(ref.org)) {
78
+ return sendJson(res, 403, { ok: false, error: 'intent capture preview is unavailable' });
79
+ }
71
80
  await deps.settings.delete(ref);
72
81
  const purged = await deps.intents.purge(ref);
73
82
  await deps.audit.emit({
@@ -89,6 +98,9 @@ export async function handleIntentInsights(req, res, ref, url, deps) {
89
98
  const identity = await authorizeTenantControl(req, res, deps.gate, deps.controlPlane, ref.org);
90
99
  if (identity === false)
91
100
  return;
101
+ if (!deps.previewOrgs.has(ref.org)) {
102
+ return sendJson(res, 403, { ok: false, error: 'intent capture preview is unavailable' });
103
+ }
92
104
  const windowName = url.searchParams.get('window') ?? '7d';
93
105
  const windowMs = WINDOWS_MS.get(windowName);
94
106
  if (windowMs === undefined) {
@@ -57,7 +57,7 @@ export function createServiceHandler(registry, options = {}) {
57
57
  let activeAudit;
58
58
  const configStore = options.configStore ?? registry.configStore;
59
59
  const alertRuleStore = options.alertRuleStore ?? new InMemoryAlertRuleStore();
60
- const [intentSettings, intentEvents, requestEvents] = createObservabilityStores(options);
60
+ const [intentSettings, intentEvents, requestEvents, intentPreviewOrgs] = createObservabilityStores(options);
61
61
  const assistantStore = options.assistantStore ?? new InMemoryAssistantStore();
62
62
  const assistantAppearance = options.assistantAppearance ?? new InMemoryAssistantAppearanceSettingsStore();
63
63
  const anonymousLimiter = new AnonymousConsumerLimiter();
@@ -76,7 +76,7 @@ export function createServiceHandler(registry, options = {}) {
76
76
  activeAudit = audit;
77
77
  const { publicTenantRouting } = mcp.mcpRoutingOptions(options, controlPlane);
78
78
  const resolveEndpointOptions = (org) => mcp.endpointUrlOptionsForOrg(options, controlPlane, org);
79
- const withIntentMode = createIntentTargetResolver(intentSettings);
79
+ const withIntentMode = createIntentTargetResolver(intentSettings, intentPreviewOrgs);
80
80
  const router = createMcpRouter(async (id) => withIntentMode(await registry.getServing(id)), {
81
81
  logger,
82
82
  tls,
@@ -122,6 +122,7 @@ export function createServiceHandler(registry, options = {}) {
122
122
  requestEvents,
123
123
  intentEvents,
124
124
  intentSettings,
125
+ previewOrgs: intentPreviewOrgs,
125
126
  audit,
126
127
  maxBody,
127
128
  tls,
@@ -39,7 +39,7 @@
39
39
  "dependencies": {
40
40
  "@modelcontextprotocol/sdk": "^1.29.0",
41
41
  "@noodle-borg/admission-limits": "0.0.0",
42
- "@noodle-borg/agent-kit": "0.89.0",
42
+ "@noodle-borg/agent-kit": "0.90.0",
43
43
  "@noodle-borg/app-package": "0.0.0",
44
44
  "@noodle-borg/assistant-gateway": "0.0.0",
45
45
  "@noodle-borg/auth": "0.0.0",
@@ -18,6 +18,7 @@ export * from './deployment-package.js';
18
18
  export * from './distribution.js';
19
19
  export * from './feedback.js';
20
20
  export * from './knowledge.js';
21
+ export * from './managed-assistant-sponsorship.js';
21
22
  export * from './platform-account-reset.js';
22
23
  export * from './platform-auth.js';
23
24
  /** Informational origin of a deployment; never an authorization or policy input. */
@@ -20,6 +20,7 @@ export * from './deployment-package.js';
20
20
  export * from './distribution.js';
21
21
  export * from './feedback.js';
22
22
  export * from './knowledge.js';
23
+ export * from './managed-assistant-sponsorship.js';
23
24
  export * from './platform-account-reset.js';
24
25
  export * from './platform-auth.js';
25
26
  // ─── Deploy ─────────────────────────────────────────────────────────────────────
@@ -0,0 +1,297 @@
1
+ import { z } from 'zod';
2
+ export declare const MANAGED_ASSISTANT_SPONSORSHIP_MAX_GRANT_TURNS_PER_DAY = 100000;
3
+ export declare const ManagedAssistantSponsorshipGrantCreateRequestSchema: z.ZodObject<{
4
+ additionalTurnsPerDay: z.ZodNumber;
5
+ startsAt: z.ZodOptional<z.ZodISODateTime>;
6
+ expiresAt: z.ZodISODateTime;
7
+ reason: z.ZodString;
8
+ idempotencyKey: z.ZodString;
9
+ }, z.core.$strict>;
10
+ export type ManagedAssistantSponsorshipGrantCreateRequest = z.infer<typeof ManagedAssistantSponsorshipGrantCreateRequestSchema>;
11
+ export declare const ManagedAssistantSponsorshipGrantRevokeRequestSchema: z.ZodObject<{
12
+ reason: z.ZodString;
13
+ idempotencyKey: z.ZodString;
14
+ }, z.core.$strict>;
15
+ export type ManagedAssistantSponsorshipGrantRevokeRequest = z.infer<typeof ManagedAssistantSponsorshipGrantRevokeRequestSchema>;
16
+ export declare const ManagedAssistantSponsorshipGrantSchema: z.ZodObject<{
17
+ id: z.ZodString;
18
+ billingAccountId: z.ZodString;
19
+ additionalTurnsPerDay: z.ZodNumber;
20
+ startsAt: z.ZodISODateTime;
21
+ expiresAt: z.ZodISODateTime;
22
+ reason: z.ZodString;
23
+ status: z.ZodEnum<{
24
+ active: "active";
25
+ revoked: "revoked";
26
+ scheduled: "scheduled";
27
+ expired: "expired";
28
+ }>;
29
+ createdAt: z.ZodISODateTime;
30
+ revokedAt: z.ZodOptional<z.ZodISODateTime>;
31
+ revocationReason: z.ZodOptional<z.ZodString>;
32
+ }, z.core.$strict>;
33
+ export type ManagedAssistantSponsorshipGrant = z.infer<typeof ManagedAssistantSponsorshipGrantSchema>;
34
+ export declare const ManagedAssistantSponsorshipResponseSchema: z.ZodObject<{
35
+ ok: z.ZodLiteral<true>;
36
+ data: z.ZodObject<{
37
+ billingAccountId: z.ZodString;
38
+ mode: z.ZodLiteral<"sponsored_beta">;
39
+ defaultTurnsPerDay: z.ZodNumber;
40
+ bonusTurnsPerDay: z.ZodNumber;
41
+ totalTurnsPerDay: z.ZodNumber;
42
+ spend: z.ZodObject<{
43
+ state: z.ZodEnum<{
44
+ normal: "normal";
45
+ approaching: "approaching";
46
+ near: "near";
47
+ limited: "limited";
48
+ closed: "closed";
49
+ }>;
50
+ allowanceUnits: z.ZodNumber;
51
+ usedUnitsToday: z.ZodNumber;
52
+ turnsRemaining: z.ZodNumber;
53
+ }, z.core.$strict>;
54
+ resetAt: z.ZodISODateTime;
55
+ grants: z.ZodArray<z.ZodObject<{
56
+ id: z.ZodString;
57
+ billingAccountId: z.ZodString;
58
+ additionalTurnsPerDay: z.ZodNumber;
59
+ startsAt: z.ZodISODateTime;
60
+ expiresAt: z.ZodISODateTime;
61
+ reason: z.ZodString;
62
+ status: z.ZodEnum<{
63
+ active: "active";
64
+ revoked: "revoked";
65
+ scheduled: "scheduled";
66
+ expired: "expired";
67
+ }>;
68
+ createdAt: z.ZodISODateTime;
69
+ revokedAt: z.ZodOptional<z.ZodISODateTime>;
70
+ revocationReason: z.ZodOptional<z.ZodString>;
71
+ }, z.core.$strict>>;
72
+ platform: z.ZodOptional<z.ZodObject<{
73
+ globalTurnsPerDay: z.ZodNumber;
74
+ spend: z.ZodObject<{
75
+ state: z.ZodEnum<{
76
+ normal: "normal";
77
+ approaching: "approaching";
78
+ near: "near";
79
+ limited: "limited";
80
+ closed: "closed";
81
+ }>;
82
+ allowanceUnits: z.ZodNumber;
83
+ usedUnitsToday: z.ZodNumber;
84
+ turnsRemaining: z.ZodNumber;
85
+ }, z.core.$strict>;
86
+ }, z.core.$strict>>;
87
+ }, z.core.$strict>;
88
+ }, z.core.$strict>;
89
+ export type ManagedAssistantSponsorshipResponse = z.infer<typeof ManagedAssistantSponsorshipResponseSchema>;
90
+ /** Client reader strips additive fields at every layer while the service output stays strict. */
91
+ export declare const ManagedAssistantSponsorshipClientResponseSchema: z.ZodObject<{
92
+ ok: z.ZodLiteral<true>;
93
+ data: z.ZodObject<{
94
+ spend: z.ZodObject<{
95
+ state: z.ZodEnum<{
96
+ normal: "normal";
97
+ approaching: "approaching";
98
+ near: "near";
99
+ limited: "limited";
100
+ closed: "closed";
101
+ }>;
102
+ allowanceUnits: z.ZodNumber;
103
+ usedUnitsToday: z.ZodNumber;
104
+ turnsRemaining: z.ZodNumber;
105
+ }, z.core.$strip>;
106
+ grants: z.ZodArray<z.ZodObject<{
107
+ id: z.ZodString;
108
+ billingAccountId: z.ZodString;
109
+ additionalTurnsPerDay: z.ZodNumber;
110
+ startsAt: z.ZodISODateTime;
111
+ expiresAt: z.ZodISODateTime;
112
+ reason: z.ZodString;
113
+ status: z.ZodEnum<{
114
+ active: "active";
115
+ revoked: "revoked";
116
+ scheduled: "scheduled";
117
+ expired: "expired";
118
+ }>;
119
+ createdAt: z.ZodISODateTime;
120
+ revokedAt: z.ZodOptional<z.ZodISODateTime>;
121
+ revocationReason: z.ZodOptional<z.ZodString>;
122
+ }, z.core.$strip>>;
123
+ platform: z.ZodOptional<z.ZodObject<{
124
+ globalTurnsPerDay: z.ZodNumber;
125
+ spend: z.ZodObject<{
126
+ state: z.ZodEnum<{
127
+ normal: "normal";
128
+ approaching: "approaching";
129
+ near: "near";
130
+ limited: "limited";
131
+ closed: "closed";
132
+ }>;
133
+ allowanceUnits: z.ZodNumber;
134
+ usedUnitsToday: z.ZodNumber;
135
+ turnsRemaining: z.ZodNumber;
136
+ }, z.core.$strip>;
137
+ }, z.core.$strip>>;
138
+ billingAccountId: z.ZodString;
139
+ mode: z.ZodLiteral<"sponsored_beta">;
140
+ defaultTurnsPerDay: z.ZodNumber;
141
+ bonusTurnsPerDay: z.ZodNumber;
142
+ totalTurnsPerDay: z.ZodNumber;
143
+ resetAt: z.ZodISODateTime;
144
+ }, z.core.$strip>;
145
+ }, z.core.$strip>;
146
+ export declare const ManagedAssistantSponsorshipGrantMutationResponseSchema: z.ZodObject<{
147
+ ok: z.ZodLiteral<true>;
148
+ data: z.ZodObject<{
149
+ replayed: z.ZodBoolean;
150
+ grant: z.ZodObject<{
151
+ id: z.ZodString;
152
+ billingAccountId: z.ZodString;
153
+ additionalTurnsPerDay: z.ZodNumber;
154
+ startsAt: z.ZodISODateTime;
155
+ expiresAt: z.ZodISODateTime;
156
+ reason: z.ZodString;
157
+ status: z.ZodEnum<{
158
+ active: "active";
159
+ revoked: "revoked";
160
+ scheduled: "scheduled";
161
+ expired: "expired";
162
+ }>;
163
+ createdAt: z.ZodISODateTime;
164
+ revokedAt: z.ZodOptional<z.ZodISODateTime>;
165
+ revocationReason: z.ZodOptional<z.ZodString>;
166
+ }, z.core.$strict>;
167
+ sponsorship: z.ZodObject<{
168
+ billingAccountId: z.ZodString;
169
+ mode: z.ZodLiteral<"sponsored_beta">;
170
+ defaultTurnsPerDay: z.ZodNumber;
171
+ bonusTurnsPerDay: z.ZodNumber;
172
+ totalTurnsPerDay: z.ZodNumber;
173
+ spend: z.ZodObject<{
174
+ state: z.ZodEnum<{
175
+ normal: "normal";
176
+ approaching: "approaching";
177
+ near: "near";
178
+ limited: "limited";
179
+ closed: "closed";
180
+ }>;
181
+ allowanceUnits: z.ZodNumber;
182
+ usedUnitsToday: z.ZodNumber;
183
+ turnsRemaining: z.ZodNumber;
184
+ }, z.core.$strict>;
185
+ resetAt: z.ZodISODateTime;
186
+ grants: z.ZodArray<z.ZodObject<{
187
+ id: z.ZodString;
188
+ billingAccountId: z.ZodString;
189
+ additionalTurnsPerDay: z.ZodNumber;
190
+ startsAt: z.ZodISODateTime;
191
+ expiresAt: z.ZodISODateTime;
192
+ reason: z.ZodString;
193
+ status: z.ZodEnum<{
194
+ active: "active";
195
+ revoked: "revoked";
196
+ scheduled: "scheduled";
197
+ expired: "expired";
198
+ }>;
199
+ createdAt: z.ZodISODateTime;
200
+ revokedAt: z.ZodOptional<z.ZodISODateTime>;
201
+ revocationReason: z.ZodOptional<z.ZodString>;
202
+ }, z.core.$strict>>;
203
+ platform: z.ZodOptional<z.ZodObject<{
204
+ globalTurnsPerDay: z.ZodNumber;
205
+ spend: z.ZodObject<{
206
+ state: z.ZodEnum<{
207
+ normal: "normal";
208
+ approaching: "approaching";
209
+ near: "near";
210
+ limited: "limited";
211
+ closed: "closed";
212
+ }>;
213
+ allowanceUnits: z.ZodNumber;
214
+ usedUnitsToday: z.ZodNumber;
215
+ turnsRemaining: z.ZodNumber;
216
+ }, z.core.$strict>;
217
+ }, z.core.$strict>>;
218
+ }, z.core.$strict>;
219
+ }, z.core.$strict>;
220
+ }, z.core.$strict>;
221
+ export type ManagedAssistantSponsorshipGrantMutationResponse = z.infer<typeof ManagedAssistantSponsorshipGrantMutationResponseSchema>;
222
+ export declare const ManagedAssistantSponsorshipGrantMutationClientResponseSchema: z.ZodObject<{
223
+ ok: z.ZodLiteral<true>;
224
+ data: z.ZodObject<{
225
+ replayed: z.ZodBoolean;
226
+ grant: z.ZodObject<{
227
+ id: z.ZodString;
228
+ billingAccountId: z.ZodString;
229
+ additionalTurnsPerDay: z.ZodNumber;
230
+ startsAt: z.ZodISODateTime;
231
+ expiresAt: z.ZodISODateTime;
232
+ reason: z.ZodString;
233
+ status: z.ZodEnum<{
234
+ active: "active";
235
+ revoked: "revoked";
236
+ scheduled: "scheduled";
237
+ expired: "expired";
238
+ }>;
239
+ createdAt: z.ZodISODateTime;
240
+ revokedAt: z.ZodOptional<z.ZodISODateTime>;
241
+ revocationReason: z.ZodOptional<z.ZodString>;
242
+ }, z.core.$strip>;
243
+ sponsorship: z.ZodObject<{
244
+ spend: z.ZodObject<{
245
+ state: z.ZodEnum<{
246
+ normal: "normal";
247
+ approaching: "approaching";
248
+ near: "near";
249
+ limited: "limited";
250
+ closed: "closed";
251
+ }>;
252
+ allowanceUnits: z.ZodNumber;
253
+ usedUnitsToday: z.ZodNumber;
254
+ turnsRemaining: z.ZodNumber;
255
+ }, z.core.$strip>;
256
+ grants: z.ZodArray<z.ZodObject<{
257
+ id: z.ZodString;
258
+ billingAccountId: z.ZodString;
259
+ additionalTurnsPerDay: z.ZodNumber;
260
+ startsAt: z.ZodISODateTime;
261
+ expiresAt: z.ZodISODateTime;
262
+ reason: z.ZodString;
263
+ status: z.ZodEnum<{
264
+ active: "active";
265
+ revoked: "revoked";
266
+ scheduled: "scheduled";
267
+ expired: "expired";
268
+ }>;
269
+ createdAt: z.ZodISODateTime;
270
+ revokedAt: z.ZodOptional<z.ZodISODateTime>;
271
+ revocationReason: z.ZodOptional<z.ZodString>;
272
+ }, z.core.$strip>>;
273
+ platform: z.ZodOptional<z.ZodObject<{
274
+ globalTurnsPerDay: z.ZodNumber;
275
+ spend: z.ZodObject<{
276
+ state: z.ZodEnum<{
277
+ normal: "normal";
278
+ approaching: "approaching";
279
+ near: "near";
280
+ limited: "limited";
281
+ closed: "closed";
282
+ }>;
283
+ allowanceUnits: z.ZodNumber;
284
+ usedUnitsToday: z.ZodNumber;
285
+ turnsRemaining: z.ZodNumber;
286
+ }, z.core.$strip>;
287
+ }, z.core.$strip>>;
288
+ billingAccountId: z.ZodString;
289
+ mode: z.ZodLiteral<"sponsored_beta">;
290
+ defaultTurnsPerDay: z.ZodNumber;
291
+ bonusTurnsPerDay: z.ZodNumber;
292
+ totalTurnsPerDay: z.ZodNumber;
293
+ resetAt: z.ZodISODateTime;
294
+ }, z.core.$strip>;
295
+ }, z.core.$strip>;
296
+ }, z.core.$strip>;
297
+ //# sourceMappingURL=managed-assistant-sponsorship.d.ts.map
@@ -0,0 +1,94 @@
1
+ import { z } from 'zod';
2
+ const strictObject = (shape) => z.strictObject(shape);
3
+ const additiveObject = (shape) => z.object(shape);
4
+ const timestamp = z.iso.datetime({ offset: true });
5
+ const billingAccountId = z.string().min(1).max(160);
6
+ const grantId = z.string().regex(/^masg_[A-Za-z0-9_-]{16,80}$/);
7
+ const reason = z.string().trim().min(3).max(500);
8
+ const idempotencyKey = z.string().trim().min(8).max(200);
9
+ export const MANAGED_ASSISTANT_SPONSORSHIP_MAX_GRANT_TURNS_PER_DAY = 100_000;
10
+ export const ManagedAssistantSponsorshipGrantCreateRequestSchema = strictObject({
11
+ additionalTurnsPerDay: z
12
+ .number()
13
+ .int()
14
+ .positive()
15
+ .max(MANAGED_ASSISTANT_SPONSORSHIP_MAX_GRANT_TURNS_PER_DAY),
16
+ startsAt: timestamp.optional(),
17
+ expiresAt: timestamp,
18
+ reason,
19
+ idempotencyKey,
20
+ });
21
+ export const ManagedAssistantSponsorshipGrantRevokeRequestSchema = strictObject({
22
+ reason,
23
+ idempotencyKey,
24
+ });
25
+ const grantShape = {
26
+ id: grantId,
27
+ billingAccountId,
28
+ additionalTurnsPerDay: z.number().int().positive(),
29
+ startsAt: timestamp,
30
+ expiresAt: timestamp,
31
+ reason,
32
+ status: z.enum(['scheduled', 'active', 'expired', 'revoked']),
33
+ createdAt: timestamp,
34
+ revokedAt: timestamp.optional(),
35
+ revocationReason: reason.optional(),
36
+ };
37
+ export const ManagedAssistantSponsorshipGrantSchema = strictObject(grantShape);
38
+ const spendShape = {
39
+ state: z.enum(['normal', 'approaching', 'near', 'limited', 'closed']),
40
+ allowanceUnits: z.number().int().nonnegative(),
41
+ usedUnitsToday: z.number().int().nonnegative(),
42
+ turnsRemaining: z.number().int().nonnegative(),
43
+ };
44
+ const sponsorshipDataShape = {
45
+ billingAccountId,
46
+ mode: z.literal('sponsored_beta'),
47
+ defaultTurnsPerDay: z.number().int().nonnegative(),
48
+ bonusTurnsPerDay: z.number().int().nonnegative(),
49
+ totalTurnsPerDay: z.number().int().nonnegative(),
50
+ spend: strictObject(spendShape),
51
+ resetAt: timestamp,
52
+ grants: z.array(ManagedAssistantSponsorshipGrantSchema),
53
+ platform: strictObject({
54
+ globalTurnsPerDay: z.number().int().nonnegative(),
55
+ spend: strictObject(spendShape),
56
+ }).optional(),
57
+ };
58
+ export const ManagedAssistantSponsorshipResponseSchema = strictObject({
59
+ ok: z.literal(true),
60
+ data: strictObject(sponsorshipDataShape),
61
+ });
62
+ const grantClientSchema = additiveObject(grantShape);
63
+ const spendClientSchema = additiveObject(spendShape);
64
+ const sponsorshipClientDataSchema = additiveObject({
65
+ ...sponsorshipDataShape,
66
+ spend: spendClientSchema,
67
+ grants: z.array(grantClientSchema),
68
+ platform: additiveObject({
69
+ globalTurnsPerDay: z.number().int().nonnegative(),
70
+ spend: spendClientSchema,
71
+ }).optional(),
72
+ });
73
+ /** Client reader strips additive fields at every layer while the service output stays strict. */
74
+ export const ManagedAssistantSponsorshipClientResponseSchema = additiveObject({
75
+ ok: z.literal(true),
76
+ data: sponsorshipClientDataSchema,
77
+ });
78
+ export const ManagedAssistantSponsorshipGrantMutationResponseSchema = strictObject({
79
+ ok: z.literal(true),
80
+ data: strictObject({
81
+ replayed: z.boolean(),
82
+ grant: ManagedAssistantSponsorshipGrantSchema,
83
+ sponsorship: strictObject(sponsorshipDataShape),
84
+ }),
85
+ });
86
+ export const ManagedAssistantSponsorshipGrantMutationClientResponseSchema = additiveObject({
87
+ ok: z.literal(true),
88
+ data: additiveObject({
89
+ replayed: z.boolean(),
90
+ grant: grantClientSchema,
91
+ sponsorship: sponsorshipClientDataSchema,
92
+ }),
93
+ });
94
+ //# sourceMappingURL=managed-assistant-sponsorship.js.map
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noodleseed/assistant",
3
- "version": "1.30.0",
3
+ "version": "1.31.0",
4
4
  "description": "Embed the Noodle Seed customer-branded assistant in your web app with managed or framework-owned UI, a framework-neutral MCP App host, a DOM-free client, and a backend session helper. Authoring and deploying the server is @noodleseed/one.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {