@standardagents/spec 0.43.0 → 0.44.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/index.js CHANGED
@@ -13,8 +13,8 @@ function defineProvider(definition) {
13
13
  if (typeof definition.baseProvider !== "function") {
14
14
  throw new Error("baseProvider must be a provider factory function");
15
15
  }
16
- const factory = ((config) => {
17
- const baseProvider = definition.baseProvider(config);
16
+ const factory = ((config, context) => {
17
+ const baseProvider = context ? definition.baseProvider(config, context) : definition.baseProvider(config);
18
18
  const commonContext = {
19
19
  providerName: definition.name,
20
20
  config,
@@ -25,11 +25,11 @@ function defineProvider(definition) {
25
25
  specificationVersion: "1",
26
26
  generate: (request) => {
27
27
  const next = () => baseProvider.generate(request);
28
- return Promise.resolve(definition.overrides?.generate?.({ ...commonContext, request }, next) ?? next());
28
+ return Promise.resolve(definition.overrides?.generate?.({ ...commonContext, state: context?.state, request }, next) ?? next());
29
29
  },
30
30
  stream: (request) => {
31
31
  const next = () => baseProvider.stream(request);
32
- return Promise.resolve(definition.overrides?.stream?.({ ...commonContext, request }, next) ?? next());
32
+ return Promise.resolve(definition.overrides?.stream?.({ ...commonContext, state: context?.state, request }, next) ?? next());
33
33
  }
34
34
  };
35
35
  if (definition.overrides?.supportsModel || baseProvider.supportsModel) {
@@ -83,7 +83,7 @@ function defineProvider(definition) {
83
83
  return baseProvider.inspectRequest(request);
84
84
  };
85
85
  return Promise.resolve(
86
- definition.overrides?.inspectRequest?.({ ...commonContext, request }, next) ?? next()
86
+ definition.overrides?.inspectRequest?.({ ...commonContext, state: context?.state, request }, next) ?? next()
87
87
  );
88
88
  };
89
89
  }
@@ -91,7 +91,7 @@ function defineProvider(definition) {
91
91
  provider.getResponseMetadata = (summary, signal) => {
92
92
  const next = () => baseProvider.getResponseMetadata?.(summary, signal) ?? Promise.resolve(null);
93
93
  return Promise.resolve(
94
- definition.overrides?.getResponseMetadata?.({ ...commonContext, summary, signal }, next) ?? next()
94
+ definition.overrides?.getResponseMetadata?.({ ...commonContext, state: context?.state, summary, signal }, next) ?? next()
95
95
  );
96
96
  };
97
97
  }
@@ -147,10 +147,12 @@ function defineTool(options) {
147
147
  name: entry.name,
148
148
  type: entry.type === "secret" ? "secret" : "text",
149
149
  required: !!entry.required,
150
+ scoped: entry.scoped,
150
151
  description: typeof entry.description === "string" ? entry.description : ""
151
152
  }));
152
153
  return {
153
154
  description: options.description,
155
+ annotations: options.annotations,
154
156
  args: options.args ?? null,
155
157
  execute: options.execute,
156
158
  variables,
@@ -200,22 +202,17 @@ function definePrompt(options) {
200
202
  }
201
203
  if (options.reasoning) {
202
204
  if (options.reasoning.level !== void 0) {
203
- if (typeof options.reasoning.level !== "number" || options.reasoning.level < 0 || options.reasoning.level > 100) {
205
+ if (typeof options.reasoning.level !== "number" || !Number.isFinite(options.reasoning.level) || options.reasoning.level < 0 || options.reasoning.level > 100) {
204
206
  throw new Error("reasoning.level must be a number between 0 and 100");
205
207
  }
206
208
  }
207
- if (options.reasoning.effort && !["low", "medium", "high"].includes(options.reasoning.effort)) {
208
- throw new Error(
209
- `Invalid reasoning.effort '${options.reasoning.effort}'. Must be one of: low, medium, high`
210
- );
211
- }
212
- if (options.reasoning.level !== void 0 && options.reasoning.effort !== void 0) {
213
- console.warn("Both reasoning.level and reasoning.effort provided. level takes precedence. effort is deprecated.");
214
- }
215
209
  }
216
210
  if (options.recentImageThreshold !== void 0 && (options.recentImageThreshold <= 0 || !Number.isInteger(options.recentImageThreshold))) {
217
211
  throw new Error("recentImageThreshold must be a positive integer");
218
212
  }
213
+ if (options.historyLimit !== void 0 && (options.historyLimit <= 0 || !Number.isInteger(options.historyLimit))) {
214
+ throw new Error("historyLimit must be a positive integer");
215
+ }
219
216
  const normalizedVariables = Array.isArray(options.variables) ? options.variables.map((entry) => ({
220
217
  name: entry.name,
221
218
  type: entry.type === "secret" ? "secret" : "text",
@@ -244,7 +241,10 @@ var VALID_HOOKS = [
244
241
  "after_tool_call_success",
245
242
  "after_tool_call_failure",
246
243
  "tool_call_started",
247
- "tool_call_done"
244
+ "tool_call_done",
245
+ "user_client_attached",
246
+ "user_client_detached",
247
+ "user_value_changed"
248
248
  ];
249
249
  function defineHook(options) {
250
250
  if (!VALID_HOOKS.includes(options.hook)) {
@@ -304,6 +304,40 @@ function isHandler(value) {
304
304
  return typeof value === "object" && value !== null && HANDLER_SYMBOL in value && value[HANDLER_SYMBOL] === true;
305
305
  }
306
306
 
307
+ // src/packing.ts
308
+ function isPacked(metadata) {
309
+ return !!metadata?.__package;
310
+ }
311
+ function belongsToPackage(metadata, packageId) {
312
+ return metadata?.__package?.packageId === packageId;
313
+ }
314
+ function isVisibleInNamespace(metadata, namespace, isEntryPoint = false) {
315
+ const hasPkg = isPacked(metadata);
316
+ if (namespace.type === "global") {
317
+ return !hasPkg || isEntryPoint;
318
+ }
319
+ const isOwnPackage = hasPkg && metadata.__package.packageId === namespace.packageId;
320
+ return isOwnPackage || hasPkg && isEntryPoint;
321
+ }
322
+ function parseQualifiedName(name) {
323
+ if (name.startsWith("@")) {
324
+ const firstSlash = name.indexOf("/");
325
+ if (firstSlash === -1) {
326
+ return [null, name];
327
+ }
328
+ const secondSlash = name.indexOf("/", firstSlash + 1);
329
+ if (secondSlash === -1) {
330
+ return [null, name];
331
+ }
332
+ return [name.substring(0, secondSlash), name.substring(secondSlash + 1)];
333
+ }
334
+ const separatorIndex = name.indexOf("/");
335
+ if (separatorIndex === -1) {
336
+ return [null, name];
337
+ }
338
+ return [name.substring(0, separatorIndex), name.substring(separatorIndex + 1)];
339
+ }
340
+
307
341
  // src/validation.ts
308
342
  var DEFINITION_ISSUE_CODES = [
309
343
  "agent_name_missing",
@@ -318,8 +352,8 @@ var DEFINITION_ISSUE_CODES = [
318
352
  "agent_legacy_type",
319
353
  "agent_session_binding_legacy_string",
320
354
  "agent_session_binding_invalid",
321
- "agent_stop_tool_response_property_missing",
322
355
  "agent_max_steps_invalid",
356
+ "agent_stop_tool_missing",
323
357
  "agent_max_session_turns_invalid",
324
358
  "agent_tool_description_missing",
325
359
  "agent_parent_hooks_invalid",
@@ -460,11 +494,11 @@ function validateAgentDefinition(def) {
460
494
  );
461
495
  }
462
496
  if (backing === "prompt") {
463
- if (side.stopTool !== void 0 && side.stopToolResponseProperty === void 0) {
497
+ if (side.stopToolResponseProperty !== void 0 && !side.stopTool) {
464
498
  error(
465
- "agent_stop_tool_response_property_missing",
499
+ "agent_stop_tool_missing",
466
500
  `${sideKey}.stopToolResponseProperty`,
467
- `${sideKey}.stopToolResponseProperty is required when ${sideKey}.stopTool is set`
501
+ `${sideKey}.stopToolResponseProperty requires stopTool`
468
502
  );
469
503
  }
470
504
  if (side.maxSteps !== void 0 && (typeof side.maxSteps !== "number" || side.maxSteps <= 0)) {
@@ -516,7 +550,7 @@ function validateAgentDefinition(def) {
516
550
  error(
517
551
  "subagent_legacy_name",
518
552
  `${path}.name`,
519
- `'name' was removed in 0.2.0 \u2014 the relationship name is 'as' (defaulting to the agent name) and the target agent is 'agent'. ${MIGRATION_URL}`
553
+ `'name' was removed in 0.2.0 \u2014 the relationship name is 'as' (defaulting to the unqualified agent name) and the target agent is 'agent'. ${MIGRATION_URL}`
520
554
  );
521
555
  }
522
556
  if (relationship.resumable !== void 0) {
@@ -556,7 +590,7 @@ function validateAgentDefinition(def) {
556
590
  `'maxInstances' must be a positive number when provided`
557
591
  );
558
592
  }
559
- const relationshipName = typeof relationship.as === "string" && relationship.as ? relationship.as : relationship.agent;
593
+ const relationshipName = typeof relationship.as === "string" && relationship.as ? relationship.as : parseQualifiedName(relationship.agent)[1];
560
594
  if (RESERVED_NAMES.has(relationshipName)) {
561
595
  error(
562
596
  "subagent_relationship_reserved_name",
@@ -758,6 +792,28 @@ var ProviderError = class extends Error {
758
792
  return this.code === "rate_limit" || this.code === "server_error" || this.code === "timeout";
759
793
  }
760
794
  };
795
+ async function resolveRequestReasoningLevels(request, lookup) {
796
+ request.signal?.throwIfAborted();
797
+ if (request.reasoning?.level === void 0) return void 0;
798
+ if (request.reasoning.levels !== void 0) return request.reasoning.levels;
799
+ let timer;
800
+ let abort;
801
+ try {
802
+ return await Promise.race([
803
+ Promise.resolve().then(() => lookup(request.model)).then((capabilities) => capabilities?.reasoningLevels, () => void 0),
804
+ new Promise((resolve) => {
805
+ timer = setTimeout(() => resolve(void 0), 250);
806
+ }),
807
+ new Promise((_resolve, reject) => {
808
+ abort = () => reject(request.signal?.reason);
809
+ request.signal?.addEventListener("abort", abort, { once: true });
810
+ })
811
+ ]);
812
+ } finally {
813
+ if (timer !== void 0) clearTimeout(timer);
814
+ if (abort) request.signal?.removeEventListener("abort", abort);
815
+ }
816
+ }
761
817
  function mapReasoningLevel(level, reasoningLevels) {
762
818
  if (!reasoningLevels) return null;
763
819
  const breakpoints = Object.keys(reasoningLevels).map(Number).sort((a, b) => a - b);
@@ -774,22 +830,6 @@ function mapReasoningLevel(level, reasoningLevels) {
774
830
  return reasoningLevels[nearest];
775
831
  }
776
832
 
777
- // src/packing.ts
778
- function isPacked(metadata) {
779
- return !!metadata?.__package;
780
- }
781
- function belongsToPackage(metadata, packageId) {
782
- return metadata?.__package?.packageId === packageId;
783
- }
784
- function isVisibleInNamespace(metadata, namespace, isEntryPoint = false) {
785
- const hasPkg = isPacked(metadata);
786
- if (namespace.type === "global") {
787
- return !hasPkg || isEntryPoint;
788
- }
789
- const isOwnPackage = hasPkg && metadata.__package.packageId === namespace.packageId;
790
- return isOwnPackage || hasPkg && isEntryPoint;
791
- }
792
-
793
833
  // src/decisions.ts
794
834
  function decide(state, options) {
795
835
  return state.decide(options);
@@ -830,9 +870,11 @@ export {
830
870
  isUserRoom,
831
871
  isVisibleInNamespace,
832
872
  mapReasoningLevel,
873
+ parseQualifiedName,
833
874
  providerConst,
834
875
  providerEnv,
835
876
  providerValue,
877
+ resolveRequestReasoningLevels,
836
878
  validateAgentDefinition,
837
879
  validateToolName
838
880
  };