@standardagents/spec 0.43.1 → 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,18 +202,10 @@ 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");
@@ -247,7 +241,10 @@ var VALID_HOOKS = [
247
241
  "after_tool_call_success",
248
242
  "after_tool_call_failure",
249
243
  "tool_call_started",
250
- "tool_call_done"
244
+ "tool_call_done",
245
+ "user_client_attached",
246
+ "user_client_detached",
247
+ "user_value_changed"
251
248
  ];
252
249
  function defineHook(options) {
253
250
  if (!VALID_HOOKS.includes(options.hook)) {
@@ -307,6 +304,40 @@ function isHandler(value) {
307
304
  return typeof value === "object" && value !== null && HANDLER_SYMBOL in value && value[HANDLER_SYMBOL] === true;
308
305
  }
309
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
+
310
341
  // src/validation.ts
311
342
  var DEFINITION_ISSUE_CODES = [
312
343
  "agent_name_missing",
@@ -321,8 +352,8 @@ var DEFINITION_ISSUE_CODES = [
321
352
  "agent_legacy_type",
322
353
  "agent_session_binding_legacy_string",
323
354
  "agent_session_binding_invalid",
324
- "agent_stop_tool_response_property_missing",
325
355
  "agent_max_steps_invalid",
356
+ "agent_stop_tool_missing",
326
357
  "agent_max_session_turns_invalid",
327
358
  "agent_tool_description_missing",
328
359
  "agent_parent_hooks_invalid",
@@ -463,11 +494,11 @@ function validateAgentDefinition(def) {
463
494
  );
464
495
  }
465
496
  if (backing === "prompt") {
466
- if (side.stopTool !== void 0 && side.stopToolResponseProperty === void 0) {
497
+ if (side.stopToolResponseProperty !== void 0 && !side.stopTool) {
467
498
  error(
468
- "agent_stop_tool_response_property_missing",
499
+ "agent_stop_tool_missing",
469
500
  `${sideKey}.stopToolResponseProperty`,
470
- `${sideKey}.stopToolResponseProperty is required when ${sideKey}.stopTool is set`
501
+ `${sideKey}.stopToolResponseProperty requires stopTool`
471
502
  );
472
503
  }
473
504
  if (side.maxSteps !== void 0 && (typeof side.maxSteps !== "number" || side.maxSteps <= 0)) {
@@ -519,7 +550,7 @@ function validateAgentDefinition(def) {
519
550
  error(
520
551
  "subagent_legacy_name",
521
552
  `${path}.name`,
522
- `'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}`
523
554
  );
524
555
  }
525
556
  if (relationship.resumable !== void 0) {
@@ -559,7 +590,7 @@ function validateAgentDefinition(def) {
559
590
  `'maxInstances' must be a positive number when provided`
560
591
  );
561
592
  }
562
- 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];
563
594
  if (RESERVED_NAMES.has(relationshipName)) {
564
595
  error(
565
596
  "subagent_relationship_reserved_name",
@@ -761,6 +792,28 @@ var ProviderError = class extends Error {
761
792
  return this.code === "rate_limit" || this.code === "server_error" || this.code === "timeout";
762
793
  }
763
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
+ }
764
817
  function mapReasoningLevel(level, reasoningLevels) {
765
818
  if (!reasoningLevels) return null;
766
819
  const breakpoints = Object.keys(reasoningLevels).map(Number).sort((a, b) => a - b);
@@ -777,22 +830,6 @@ function mapReasoningLevel(level, reasoningLevels) {
777
830
  return reasoningLevels[nearest];
778
831
  }
779
832
 
780
- // src/packing.ts
781
- function isPacked(metadata) {
782
- return !!metadata?.__package;
783
- }
784
- function belongsToPackage(metadata, packageId) {
785
- return metadata?.__package?.packageId === packageId;
786
- }
787
- function isVisibleInNamespace(metadata, namespace, isEntryPoint = false) {
788
- const hasPkg = isPacked(metadata);
789
- if (namespace.type === "global") {
790
- return !hasPkg || isEntryPoint;
791
- }
792
- const isOwnPackage = hasPkg && metadata.__package.packageId === namespace.packageId;
793
- return isOwnPackage || hasPkg && isEntryPoint;
794
- }
795
-
796
833
  // src/decisions.ts
797
834
  function decide(state, options) {
798
835
  return state.decide(options);
@@ -833,9 +870,11 @@ export {
833
870
  isUserRoom,
834
871
  isVisibleInNamespace,
835
872
  mapReasoningLevel,
873
+ parseQualifiedName,
836
874
  providerConst,
837
875
  providerEnv,
838
876
  providerValue,
877
+ resolveRequestReasoningLevels,
839
878
  validateAgentDefinition,
840
879
  validateToolName
841
880
  };