@contractspec/lib.ai-agent 2.4.0 → 2.6.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 (100) hide show
  1. package/dist/agent/agent-factory.js +97 -67
  2. package/dist/agent/contract-spec-agent.js +97 -67
  3. package/dist/agent/index.js +140 -100
  4. package/dist/agent/json-runner.js +103 -71
  5. package/dist/agent/unified-agent.d.ts +4 -0
  6. package/dist/agent/unified-agent.js +134 -96
  7. package/dist/approval/index.js +86 -62
  8. package/dist/approval/workflow.d.ts +2 -0
  9. package/dist/approval/workflow.js +86 -62
  10. package/dist/exporters/claude-agent-exporter.js +90 -66
  11. package/dist/exporters/index.js +100 -76
  12. package/dist/exporters/opencode-exporter.js +96 -72
  13. package/dist/exporters/types.d.ts +2 -0
  14. package/dist/i18n/catalogs/en.js +20 -0
  15. package/dist/i18n/catalogs/es.js +20 -0
  16. package/dist/i18n/catalogs/fr.js +20 -0
  17. package/dist/i18n/catalogs/index.js +60 -0
  18. package/dist/i18n/index.js +85 -61
  19. package/dist/i18n/keys.d.ts +16 -0
  20. package/dist/i18n/keys.js +5 -1
  21. package/dist/i18n/locale.d.ts +3 -28
  22. package/dist/i18n/locale.js +7 -18
  23. package/dist/i18n/messages.d.ts +9 -60
  24. package/dist/i18n/messages.js +71 -60
  25. package/dist/index.js +88 -64
  26. package/dist/interop/index.js +117 -79
  27. package/dist/interop/spec-consumer.d.ts +1 -0
  28. package/dist/interop/spec-consumer.js +92 -66
  29. package/dist/interop/tool-consumer.d.ts +1 -0
  30. package/dist/interop/tool-consumer.js +110 -74
  31. package/dist/interop/types.d.ts +10 -0
  32. package/dist/knowledge/index.js +85 -61
  33. package/dist/knowledge/injector.js +85 -61
  34. package/dist/node/agent/agent-factory.js +97 -67
  35. package/dist/node/agent/contract-spec-agent.js +97 -67
  36. package/dist/node/agent/index.js +140 -100
  37. package/dist/node/agent/json-runner.js +103 -71
  38. package/dist/node/agent/unified-agent.js +134 -96
  39. package/dist/node/approval/index.js +86 -62
  40. package/dist/node/approval/workflow.js +86 -62
  41. package/dist/node/exporters/claude-agent-exporter.js +90 -66
  42. package/dist/node/exporters/index.js +100 -76
  43. package/dist/node/exporters/opencode-exporter.js +96 -72
  44. package/dist/node/i18n/catalogs/en.js +20 -0
  45. package/dist/node/i18n/catalogs/es.js +20 -0
  46. package/dist/node/i18n/catalogs/fr.js +20 -0
  47. package/dist/node/i18n/catalogs/index.js +60 -0
  48. package/dist/node/i18n/index.js +85 -61
  49. package/dist/node/i18n/keys.js +5 -1
  50. package/dist/node/i18n/locale.js +7 -18
  51. package/dist/node/i18n/messages.js +71 -60
  52. package/dist/node/index.js +88 -64
  53. package/dist/node/interop/index.js +117 -79
  54. package/dist/node/interop/spec-consumer.js +92 -66
  55. package/dist/node/interop/tool-consumer.js +110 -74
  56. package/dist/node/knowledge/index.js +85 -61
  57. package/dist/node/knowledge/injector.js +85 -61
  58. package/dist/node/providers/claude-agent-sdk/adapter.js +103 -74
  59. package/dist/node/providers/claude-agent-sdk/index.js +103 -74
  60. package/dist/node/providers/claude-agent-sdk/tool-bridge.js +88 -64
  61. package/dist/node/providers/index.js +116 -86
  62. package/dist/node/providers/opencode-sdk/adapter.js +102 -73
  63. package/dist/node/providers/opencode-sdk/agent-bridge.js +89 -65
  64. package/dist/node/providers/opencode-sdk/index.js +102 -73
  65. package/dist/node/providers/opencode-sdk/tool-bridge.js +88 -64
  66. package/dist/node/providers/registry.js +96 -66
  67. package/dist/node/providers/types.js +2122 -2
  68. package/dist/node/spec/index.js +88 -64
  69. package/dist/node/spec/registry.js +87 -63
  70. package/dist/node/spec/spec.js +86 -62
  71. package/dist/node/telemetry/index.js +2122 -3
  72. package/dist/node/telemetry/posthog.js +2123 -3
  73. package/dist/node/tools/index.js +90 -63
  74. package/dist/node/tools/knowledge-tool.js +85 -61
  75. package/dist/node/tools/mcp-server.js +86 -62
  76. package/dist/node/tools/tool-adapter.js +89 -62
  77. package/dist/providers/claude-agent-sdk/adapter.js +103 -74
  78. package/dist/providers/claude-agent-sdk/index.js +103 -74
  79. package/dist/providers/claude-agent-sdk/tool-bridge.js +88 -64
  80. package/dist/providers/index.js +116 -86
  81. package/dist/providers/opencode-sdk/adapter.js +102 -73
  82. package/dist/providers/opencode-sdk/agent-bridge.js +89 -65
  83. package/dist/providers/opencode-sdk/index.js +102 -73
  84. package/dist/providers/opencode-sdk/tool-bridge.js +88 -64
  85. package/dist/providers/registry.d.ts +2 -2
  86. package/dist/providers/registry.js +96 -66
  87. package/dist/providers/types.d.ts +5 -1
  88. package/dist/providers/types.js +2122 -2
  89. package/dist/spec/index.js +88 -64
  90. package/dist/spec/registry.d.ts +1 -1
  91. package/dist/spec/registry.js +87 -63
  92. package/dist/spec/spec.js +86 -62
  93. package/dist/telemetry/index.js +2122 -3
  94. package/dist/telemetry/posthog.js +2123 -3
  95. package/dist/tools/index.js +90 -63
  96. package/dist/tools/knowledge-tool.js +85 -61
  97. package/dist/tools/mcp-server.js +86 -62
  98. package/dist/tools/tool-adapter.js +89 -62
  99. package/dist/types.d.ts +2 -0
  100. package/package.json +6 -6
@@ -603,6 +603,26 @@ var init_en = __esm(() => {
603
603
  value: "[MCPToolServer] Stopped {name}",
604
604
  description: "Log message when MCP tool server stops",
605
605
  placeholders: [{ name: "name", type: "string" }]
606
+ },
607
+ "error.telemetry.posthogAiRequired": {
608
+ value: "PostHog LLM Analytics requires @posthog/ai to be installed. Run: npm install @posthog/ai posthog-node",
609
+ description: "Error when PostHog AI dependency is missing"
610
+ },
611
+ "error.telemetry.posthogClientOrKeyRequired": {
612
+ value: "PostHog LLM Analytics requires either a client instance or an apiKey.",
613
+ description: "Error when PostHog client or API key is not configured"
614
+ },
615
+ "error.telemetry.posthogNodeRequired": {
616
+ value: "PostHog LLM Analytics requires posthog-node to be installed. Run: npm install posthog-node",
617
+ description: "Error when posthog-node dependency is missing"
618
+ },
619
+ "error.provider.notAvailable": {
620
+ value: "Provider '{provider}' is not available{reason}",
621
+ description: "Error when a provider is unavailable",
622
+ placeholders: [
623
+ { name: "provider", type: "string" },
624
+ { name: "reason", type: "string" }
625
+ ]
606
626
  }
607
627
  }
608
628
  });
@@ -1214,6 +1234,26 @@ var init_fr = __esm(() => {
1214
1234
  value: "[MCPToolServer] {name} arr\xEAt\xE9",
1215
1235
  description: "Log message when MCP tool server stops",
1216
1236
  placeholders: [{ name: "name", type: "string" }]
1237
+ },
1238
+ "error.telemetry.posthogAiRequired": {
1239
+ value: "PostHog LLM Analytics n\xE9cessite l'installation de @posthog/ai. Ex\xE9cutez : npm install @posthog/ai posthog-node",
1240
+ description: "Error when PostHog AI dependency is missing"
1241
+ },
1242
+ "error.telemetry.posthogClientOrKeyRequired": {
1243
+ value: "PostHog LLM Analytics n\xE9cessite soit une instance client, soit une apiKey.",
1244
+ description: "Error when PostHog client or API key is not configured"
1245
+ },
1246
+ "error.telemetry.posthogNodeRequired": {
1247
+ value: "PostHog LLM Analytics n\xE9cessite l'installation de posthog-node. Ex\xE9cutez : npm install posthog-node",
1248
+ description: "Error when posthog-node dependency is missing"
1249
+ },
1250
+ "error.provider.notAvailable": {
1251
+ value: "Le fournisseur \xAB {provider} \xBB n'est pas disponible{reason}",
1252
+ description: "Error when a provider is unavailable",
1253
+ placeholders: [
1254
+ { name: "provider", type: "string" },
1255
+ { name: "reason", type: "string" }
1256
+ ]
1217
1257
  }
1218
1258
  }
1219
1259
  });
@@ -1859,78 +1899,58 @@ var init_es = __esm(() => {
1859
1899
  value: "[MCPToolServer] Detenido {name}",
1860
1900
  description: "Mensaje de registro cuando el servidor de herramientas MCP se detiene",
1861
1901
  placeholders: [{ name: "name", type: "string" }]
1902
+ },
1903
+ "error.telemetry.posthogAiRequired": {
1904
+ value: "PostHog LLM Analytics requiere que @posthog/ai est\xE9 instalado. Ejecute: npm install @posthog/ai posthog-node",
1905
+ description: "Error when PostHog AI dependency is missing"
1906
+ },
1907
+ "error.telemetry.posthogClientOrKeyRequired": {
1908
+ value: "PostHog LLM Analytics requiere una instancia de cliente o una apiKey.",
1909
+ description: "Error when PostHog client or API key is not configured"
1910
+ },
1911
+ "error.telemetry.posthogNodeRequired": {
1912
+ value: "PostHog LLM Analytics requiere que posthog-node est\xE9 instalado. Ejecute: npm install posthog-node",
1913
+ description: "Error when posthog-node dependency is missing"
1914
+ },
1915
+ "error.provider.notAvailable": {
1916
+ value: "El proveedor '{provider}' no est\xE1 disponible{reason}",
1917
+ description: "Error when a provider is unavailable",
1918
+ placeholders: [
1919
+ { name: "provider", type: "string" },
1920
+ { name: "reason", type: "string" }
1921
+ ]
1862
1922
  }
1863
1923
  }
1864
1924
  });
1865
1925
  });
1866
1926
 
1867
- // src/i18n/locale.ts
1868
- function resolveLocale(specLocale, runtimeLocale) {
1869
- const raw = runtimeLocale ?? specLocale ?? DEFAULT_LOCALE;
1870
- if (isSupportedLocale(raw)) {
1871
- return raw;
1872
- }
1873
- const base = raw.split("-")[0];
1874
- if (base && isSupportedLocale(base)) {
1875
- return base;
1876
- }
1877
- return DEFAULT_LOCALE;
1878
- }
1879
- function isSupportedLocale(locale) {
1880
- return SUPPORTED_LOCALES.includes(locale);
1881
- }
1882
- var DEFAULT_LOCALE = "en", SUPPORTED_LOCALES;
1883
- var init_locale = __esm(() => {
1884
- SUPPORTED_LOCALES = ["en", "fr", "es"];
1885
- });
1886
-
1887
1927
  // src/i18n/messages.ts
1888
- import { TranslationRegistry } from "@contractspec/lib.contracts-spec/translations";
1889
- function getRegistry() {
1890
- if (!sharedRegistry) {
1891
- sharedRegistry = new TranslationRegistry([
1892
- enMessages,
1893
- frMessages,
1894
- esMessages
1895
- ]);
1896
- }
1897
- return sharedRegistry;
1898
- }
1899
- function interpolate(template, params) {
1900
- if (!params)
1901
- return template;
1902
- return template.replace(/\{(\w+)\}/g, (match, key) => {
1903
- if (key in params) {
1904
- return String(params[key]);
1905
- }
1906
- return match;
1907
- });
1908
- }
1909
- function createAgentI18n(specLocale, runtimeLocale) {
1910
- const locale = resolveLocale(specLocale, runtimeLocale);
1911
- const registry = getRegistry();
1912
- return {
1913
- locale,
1914
- t(key, params) {
1915
- const raw = registry.getValue(SPEC_KEY, key, locale, key);
1916
- return interpolate(raw, params);
1917
- }
1918
- };
1919
- }
1920
- function getDefaultI18n() {
1921
- return createAgentI18n(DEFAULT_LOCALE);
1922
- }
1923
- function resetI18nRegistry() {
1924
- sharedRegistry = null;
1925
- }
1926
- var SPEC_KEY = "ai-agent.messages", sharedRegistry = null;
1928
+ import {
1929
+ createI18nFactory
1930
+ } from "@contractspec/lib.contracts-spec/translations";
1931
+ var factory, createAgentI18n, getDefaultI18n, resetI18nRegistry;
1927
1932
  var init_messages = __esm(() => {
1928
1933
  init_en();
1929
1934
  init_fr();
1930
1935
  init_es();
1931
- init_locale();
1936
+ factory = createI18nFactory({
1937
+ specKey: "ai-agent.messages",
1938
+ catalogs: [enMessages, frMessages, esMessages]
1939
+ });
1940
+ createAgentI18n = factory.create;
1941
+ getDefaultI18n = factory.getDefault;
1942
+ resetI18nRegistry = factory.resetRegistry;
1932
1943
  });
1933
1944
 
1945
+ // src/i18n/locale.ts
1946
+ import {
1947
+ DEFAULT_LOCALE,
1948
+ SUPPORTED_LOCALES,
1949
+ resolveLocale,
1950
+ isSupportedLocale
1951
+ } from "@contractspec/lib.contracts-spec/translations";
1952
+ var init_locale = () => {};
1953
+
1934
1954
  // src/i18n/keys.ts
1935
1955
  var AGENT_KEYS, KNOWLEDGE_KEYS, TOOL_KEYS, INTEROP_KEYS, ERROR_KEYS, EXPORT_KEYS, APPROVAL_KEYS, LOG_KEYS, I18N_KEYS;
1936
1956
  var init_keys = __esm(() => {
@@ -2025,7 +2045,11 @@ var init_keys = __esm(() => {
2025
2045
  "error.provider.sdkNotInstalled": "error.provider.sdkNotInstalled",
2026
2046
  "error.provider.contextCreation": "error.provider.contextCreation",
2027
2047
  "error.provider.executionFailed": "error.provider.executionFailed",
2028
- "error.provider.streamFailed": "error.provider.streamFailed"
2048
+ "error.provider.streamFailed": "error.provider.streamFailed",
2049
+ "error.provider.notAvailable": "error.provider.notAvailable",
2050
+ "error.telemetry.posthogAiRequired": "error.telemetry.posthogAiRequired",
2051
+ "error.telemetry.posthogClientOrKeyRequired": "error.telemetry.posthogClientOrKeyRequired",
2052
+ "error.telemetry.posthogNodeRequired": "error.telemetry.posthogNodeRequired"
2029
2053
  };
2030
2054
  EXPORT_KEYS = {
2031
2055
  "export.agentConfiguration": "export.agentConfiguration",
@@ -2105,7 +2129,7 @@ var init_i18n = __esm(() => {
2105
2129
 
2106
2130
  // src/spec/spec.ts
2107
2131
  function defineAgent(spec) {
2108
- const i18n = getDefaultI18n();
2132
+ const i18n = createAgentI18n(spec.locale);
2109
2133
  if (!spec.meta?.key) {
2110
2134
  throw new Error(i18n.t("error.agentKeyRequired"));
2111
2135
  }
@@ -2283,6 +2307,7 @@ function specToolToAISDKTool(specTool, handler, context = {}) {
2283
2307
  sessionId: context.sessionId ?? "unknown",
2284
2308
  tenantId: context.tenantId,
2285
2309
  actorId: context.actorId,
2310
+ locale: context.locale,
2286
2311
  metadata: context.metadata,
2287
2312
  signal: context.signal
2288
2313
  });
@@ -2295,7 +2320,9 @@ function specToolsToAISDKTools(specTools, handlers, context = {}) {
2295
2320
  for (const specTool of specTools) {
2296
2321
  const handler = handlers.get(specTool.name);
2297
2322
  if (!handler) {
2298
- throw new Error(getDefaultI18n().t("error.missingToolHandler", { name: specTool.name }));
2323
+ throw new Error(createAgentI18n(context.locale).t("error.missingToolHandler", {
2324
+ name: specTool.name
2325
+ }));
2299
2326
  }
2300
2327
  tools[specTool.name] = specToolToAISDKTool(specTool, handler, context);
2301
2328
  }
@@ -2802,14 +2829,14 @@ async function importPostHogAI() {
2802
2829
  try {
2803
2830
  return await import("@posthog/ai");
2804
2831
  } catch {
2805
- throw new Error("PostHog LLM Analytics requires @posthog/ai to be installed. Run: npm install @posthog/ai posthog-node");
2832
+ throw new Error(createAgentI18n().t("error.telemetry.posthogAiRequired"));
2806
2833
  }
2807
2834
  }
2808
2835
  async function resolvePostHogClient(config) {
2809
2836
  if (config.client)
2810
2837
  return config.client;
2811
2838
  if (!config.apiKey) {
2812
- throw new Error("PostHog LLM Analytics requires either a client instance or an apiKey.");
2839
+ throw new Error(createAgentI18n().t("error.telemetry.posthogClientOrKeyRequired"));
2813
2840
  }
2814
2841
  try {
2815
2842
  const { PostHog } = await import("posthog-node");
@@ -2817,7 +2844,7 @@ async function resolvePostHogClient(config) {
2817
2844
  host: config.host ?? "https://us.i.posthog.com"
2818
2845
  });
2819
2846
  } catch {
2820
- throw new Error("PostHog LLM Analytics requires posthog-node to be installed. Run: npm install posthog-node");
2847
+ throw new Error(createAgentI18n().t("error.telemetry.posthogNodeRequired"));
2821
2848
  }
2822
2849
  }
2823
2850
  function mapTokenUsage(usage) {
@@ -2859,6 +2886,9 @@ function asDateIso(value) {
2859
2886
  return value.toISOString();
2860
2887
  return;
2861
2888
  }
2889
+ var init_posthog = __esm(() => {
2890
+ init_i18n();
2891
+ });
2862
2892
 
2863
2893
  // src/agent/contract-spec-agent.ts
2864
2894
  var exports_contract_spec_agent = {};
@@ -3063,7 +3093,7 @@ ${params.prompt}` : params.prompt;
3063
3093
  posthogTraceId: params.traceId,
3064
3094
  posthogProperties: mergedProperties
3065
3095
  };
3066
- const { createPostHogTracedModel: createPostHogTracedModel2 } = await Promise.resolve().then(() => exports_posthog);
3096
+ const { createPostHogTracedModel: createPostHogTracedModel2 } = await Promise.resolve().then(() => (init_posthog(), exports_posthog));
3067
3097
  return createPostHogTracedModel2(this.config.model, posthogConfig, tracingOptions);
3068
3098
  }
3069
3099
  }
@@ -3085,6 +3115,7 @@ var init_contract_spec_agent = __esm(() => {
3085
3115
  // src/providers/types.ts
3086
3116
  var ExternalProviderError, ProviderNotAvailableError, ProviderExecutionError, ContextCreationError;
3087
3117
  var init_types = __esm(() => {
3118
+ init_i18n();
3088
3119
  ExternalProviderError = class ExternalProviderError extends Error {
3089
3120
  provider;
3090
3121
  code;
@@ -3098,8 +3129,12 @@ var init_types = __esm(() => {
3098
3129
  }
3099
3130
  };
3100
3131
  ProviderNotAvailableError = class ProviderNotAvailableError extends ExternalProviderError {
3101
- constructor(provider, reason) {
3102
- super(`Provider '${provider}' is not available${reason ? `: ${reason}` : ""}`, provider, "PROVIDER_NOT_AVAILABLE");
3132
+ constructor(provider, reason, locale) {
3133
+ const i18n = createAgentI18n(locale);
3134
+ super(i18n.t("error.provider.notAvailable", {
3135
+ provider,
3136
+ reason: reason ? `: ${reason}` : ""
3137
+ }), provider, "PROVIDER_NOT_AVAILABLE");
3103
3138
  this.name = "ProviderNotAvailableError";
3104
3139
  }
3105
3140
  };
@@ -3121,7 +3156,7 @@ var init_types = __esm(() => {
3121
3156
  function specToolToClaudeAgentTool(tool3, handler, context) {
3122
3157
  return {
3123
3158
  name: tool3.name,
3124
- description: tool3.description ?? getDefaultI18n().t("tool.fallbackDescription", { name: tool3.name }),
3159
+ description: tool3.description ?? createAgentI18n().t("tool.fallbackDescription", { name: tool3.name }),
3125
3160
  input_schema: normalizeSchema(tool3.schema),
3126
3161
  requires_confirmation: tool3.requiresApproval ?? !tool3.automationSafe,
3127
3162
  execute: async (input) => {
@@ -3141,7 +3176,7 @@ function specToolsToClaudeAgentTools(tools, handlers, context) {
3141
3176
  return tools.filter((tool3) => handlers.has(tool3.name)).map((tool3) => {
3142
3177
  const handler = handlers.get(tool3.name);
3143
3178
  if (!handler) {
3144
- throw new Error(getDefaultI18n().t("error.handlerNotFoundForTool", {
3179
+ throw new Error(createAgentI18n().t("error.handlerNotFoundForTool", {
3145
3180
  name: tool3.name
3146
3181
  }));
3147
3182
  }
@@ -3174,7 +3209,7 @@ function claudeAgentToolsToSpecTools(claudeTools) {
3174
3209
  function specToolToExternalTool(tool3, handler, context) {
3175
3210
  return {
3176
3211
  name: tool3.name,
3177
- description: tool3.description ?? getDefaultI18n().t("tool.fallbackDescription", { name: tool3.name }),
3212
+ description: tool3.description ?? createAgentI18n().t("tool.fallbackDescription", { name: tool3.name }),
3178
3213
  inputSchema: tool3.schema ?? { type: "object" },
3179
3214
  requiresApproval: tool3.requiresApproval ?? !tool3.automationSafe,
3180
3215
  execute: handler ? async (input) => {
@@ -3370,7 +3405,7 @@ class ClaudeAgentSDKProvider {
3370
3405
  }
3371
3406
  async createContext(spec) {
3372
3407
  if (!this.isAvailable()) {
3373
- throw new ProviderNotAvailableError(this.name, getDefaultI18n().t("error.provider.sdkNotConfigured"));
3408
+ throw new ProviderNotAvailableError(this.name, createAgentI18n(this.config.locale).t("error.provider.sdkNotConfigured"));
3374
3409
  }
3375
3410
  try {
3376
3411
  const toolSet = {};
@@ -3395,7 +3430,7 @@ class ClaudeAgentSDKProvider {
3395
3430
  cleanup: async () => {}
3396
3431
  };
3397
3432
  } catch (error) {
3398
- throw new ContextCreationError(this.name, getDefaultI18n().t("error.provider.contextCreation", {
3433
+ throw new ContextCreationError(this.name, createAgentI18n(this.config.locale).t("error.provider.contextCreation", {
3399
3434
  error: error instanceof Error ? error.message : String(error)
3400
3435
  }), error instanceof Error ? error : undefined);
3401
3436
  }
@@ -3453,7 +3488,7 @@ ${params.systemOverride}` : context.spec.instructions;
3453
3488
  }
3454
3489
  };
3455
3490
  } catch (error) {
3456
- throw new ProviderExecutionError(this.name, getDefaultI18n().t("error.provider.executionFailed", {
3491
+ throw new ProviderExecutionError(this.name, createAgentI18n(this.config.locale).t("error.provider.executionFailed", {
3457
3492
  error: error instanceof Error ? error.message : String(error)
3458
3493
  }), error instanceof Error ? error : undefined);
3459
3494
  }
@@ -3535,7 +3570,7 @@ ${params.systemOverride}` : context.spec.instructions;
3535
3570
  }
3536
3571
  };
3537
3572
  } catch (error) {
3538
- throw new ProviderExecutionError(this.name, getDefaultI18n().t("error.provider.streamFailed", {
3573
+ throw new ProviderExecutionError(this.name, createAgentI18n(this.config.locale).t("error.provider.streamFailed", {
3539
3574
  error: error instanceof Error ? error.message : String(error)
3540
3575
  }), error instanceof Error ? error : undefined);
3541
3576
  }
@@ -3545,7 +3580,7 @@ ${params.systemOverride}` : context.spec.instructions;
3545
3580
  const module = __require("@anthropic-ai/claude-agent-sdk");
3546
3581
  return module.default ?? module;
3547
3582
  } catch {
3548
- throw new ProviderNotAvailableError(this.name, getDefaultI18n().t("error.provider.claudeSdkMissing"));
3583
+ throw new ProviderNotAvailableError(this.name, createAgentI18n(this.config.locale).t("error.provider.claudeSdkMissing"));
3549
3584
  }
3550
3585
  }
3551
3586
  prepareToolsForSDK(context, params) {
@@ -3555,7 +3590,7 @@ ${params.systemOverride}` : context.spec.instructions;
3555
3590
  if (externalTool?.execute) {
3556
3591
  handlers.set(tool3.name, async (input) => {
3557
3592
  if (!externalTool.execute) {
3558
- throw new Error(getDefaultI18n().t("error.toolNoExecuteHandler", {
3593
+ throw new Error(createAgentI18n(this.config.locale).t("error.toolNoExecuteHandler", {
3559
3594
  name: tool3.name
3560
3595
  }));
3561
3596
  }
@@ -3579,7 +3614,7 @@ ${params.systemOverride}` : context.spec.instructions;
3579
3614
  return {
3580
3615
  toolCallId: toolCall.toolCallId,
3581
3616
  toolName: toolCall.toolName,
3582
- output: getDefaultI18n().t("error.toolNotFoundOrNoHandler", {
3617
+ output: createAgentI18n(this.config.locale).t("error.toolNotFoundOrNoHandler", {
3583
3618
  name: toolCall.toolName
3584
3619
  })
3585
3620
  };
@@ -3664,7 +3699,7 @@ var init_claude_agent_sdk = __esm(() => {
3664
3699
  function specToolToOpenCodeTool(tool3) {
3665
3700
  return {
3666
3701
  name: tool3.name,
3667
- description: tool3.description ?? getDefaultI18n().t("tool.fallbackDescription", { name: tool3.name }),
3702
+ description: tool3.description ?? createAgentI18n().t("tool.fallbackDescription", { name: tool3.name }),
3668
3703
  parameters: normalizeToOpenCodeParameters(tool3.schema),
3669
3704
  permission: getPermissionLevel(tool3)
3670
3705
  };
@@ -3696,7 +3731,7 @@ function openCodeToolsToSpecTools(openCodeTools) {
3696
3731
  function specToolToExternalToolForOpenCode(tool3, handler, context) {
3697
3732
  return {
3698
3733
  name: tool3.name,
3699
- description: tool3.description ?? getDefaultI18n().t("tool.fallbackDescription", { name: tool3.name }),
3734
+ description: tool3.description ?? createAgentI18n().t("tool.fallbackDescription", { name: tool3.name }),
3700
3735
  inputSchema: tool3.schema ?? { type: "object" },
3701
3736
  requiresApproval: tool3.requiresApproval ?? !tool3.automationSafe,
3702
3737
  execute: handler ? async (input) => {
@@ -3760,7 +3795,7 @@ async function executeToolCall(toolCall, handlers) {
3760
3795
  if (!handler) {
3761
3796
  return {
3762
3797
  tool_call_id: toolCall.id,
3763
- output: getDefaultI18n().t("error.toolNotFoundOrNoHandler", {
3798
+ output: createAgentI18n().t("error.toolNotFoundOrNoHandler", {
3764
3799
  name: toolCall.name
3765
3800
  }),
3766
3801
  is_error: true
@@ -3857,7 +3892,7 @@ function specToOpenCodeMarkdown(spec, options) {
3857
3892
  };
3858
3893
  }
3859
3894
  function buildMarkdownBody(spec) {
3860
- const i18n = getDefaultI18n();
3895
+ const i18n = createAgentI18n(spec.locale);
3861
3896
  const lines = [];
3862
3897
  lines.push(`# ${spec.meta.key}`);
3863
3898
  lines.push("");
@@ -3979,7 +4014,7 @@ class OpenCodeSDKProvider {
3979
4014
  }
3980
4015
  async createContext(spec) {
3981
4016
  if (!this.isAvailable()) {
3982
- throw new ProviderNotAvailableError(this.name, getDefaultI18n().t("error.provider.sdkNotInstalled"));
4017
+ throw new ProviderNotAvailableError(this.name, createAgentI18n(this.config.locale).t("error.provider.sdkNotInstalled"));
3983
4018
  }
3984
4019
  try {
3985
4020
  const sdk = await this.loadSDK();
@@ -4018,7 +4053,7 @@ class OpenCodeSDKProvider {
4018
4053
  }
4019
4054
  };
4020
4055
  } catch (error) {
4021
- throw new ContextCreationError(this.name, getDefaultI18n().t("error.provider.contextCreation", {
4056
+ throw new ContextCreationError(this.name, createAgentI18n(this.config.locale).t("error.provider.contextCreation", {
4022
4057
  error: error instanceof Error ? error.message : String(error)
4023
4058
  }), error instanceof Error ? error : undefined);
4024
4059
  }
@@ -4068,7 +4103,7 @@ ${params.systemOverride}` : context.spec.instructions;
4068
4103
  }
4069
4104
  };
4070
4105
  } catch (error) {
4071
- throw new ProviderExecutionError(this.name, getDefaultI18n().t("error.provider.executionFailed", {
4106
+ throw new ProviderExecutionError(this.name, createAgentI18n(this.config.locale).t("error.provider.executionFailed", {
4072
4107
  error: error instanceof Error ? error.message : String(error)
4073
4108
  }), error instanceof Error ? error : undefined);
4074
4109
  }
@@ -4156,7 +4191,7 @@ ${params.systemOverride}` : context.spec.instructions;
4156
4191
  }
4157
4192
  };
4158
4193
  } catch (error) {
4159
- throw new ProviderExecutionError(this.name, getDefaultI18n().t("error.provider.streamFailed", {
4194
+ throw new ProviderExecutionError(this.name, createAgentI18n(this.config.locale).t("error.provider.streamFailed", {
4160
4195
  error: error instanceof Error ? error.message : String(error)
4161
4196
  }), error instanceof Error ? error : undefined);
4162
4197
  }
@@ -4166,7 +4201,7 @@ ${params.systemOverride}` : context.spec.instructions;
4166
4201
  const module = __require("@opencode-ai/sdk");
4167
4202
  return module;
4168
4203
  } catch {
4169
- throw new ProviderNotAvailableError(this.name, getDefaultI18n().t("error.provider.opencodeSdkMissing"));
4204
+ throw new ProviderNotAvailableError(this.name, createAgentI18n(this.config.locale).t("error.provider.opencodeSdkMissing"));
4170
4205
  }
4171
4206
  }
4172
4207
  getHostname() {
@@ -4278,7 +4313,7 @@ function resolveModel(options) {
4278
4313
  if (options.provider) {
4279
4314
  return createProvider(options.provider).getModel();
4280
4315
  }
4281
- throw new Error(getDefaultI18n().t("error.jsonRunner.requiresModel"));
4316
+ throw new Error(createAgentI18n(options.locale).t("error.jsonRunner.requiresModel"));
4282
4317
  }
4283
4318
  function applyModelSettings(model, settings) {
4284
4319
  const { temperature } = settings;
@@ -4295,10 +4330,12 @@ function buildInstructions(base, locale, system) {
4295
4330
 
4296
4331
  `);
4297
4332
  }
4298
- function ensureToolHandlers(spec, handlers) {
4333
+ function ensureToolHandlers(spec, handlers, locale) {
4299
4334
  for (const tool3 of spec.tools) {
4300
4335
  if (!handlers.has(tool3.name)) {
4301
- throw new Error(getDefaultI18n().t("error.missingToolHandler", { name: tool3.name }));
4336
+ throw new Error(createAgentI18n(locale).t("error.missingToolHandler", {
4337
+ name: tool3.name
4338
+ }));
4302
4339
  }
4303
4340
  }
4304
4341
  }
@@ -4314,7 +4351,7 @@ async function createAgentJsonRunner(options) {
4314
4351
  maxSteps: options.maxSteps ?? baseSpec.maxSteps
4315
4352
  };
4316
4353
  const toolHandlers = options.toolHandlers ?? new Map;
4317
- ensureToolHandlers(spec, toolHandlers);
4354
+ ensureToolHandlers(spec, toolHandlers, options.locale);
4318
4355
  const agent = await ContractSpecAgent.create({
4319
4356
  spec,
4320
4357
  model,
@@ -4348,6 +4385,9 @@ class UnifiedAgent {
4348
4385
  messageCount: 0
4349
4386
  };
4350
4387
  }
4388
+ i18n(runtimeLocale) {
4389
+ return createAgentI18n(this.spec.locale, runtimeLocale ?? this.config.locale);
4390
+ }
4351
4391
  async initialize() {
4352
4392
  const backend = this.config.backend;
4353
4393
  try {
@@ -4362,14 +4402,14 @@ class UnifiedAgent {
4362
4402
  await this.initializeOpenCodeSDK();
4363
4403
  break;
4364
4404
  default:
4365
- throw new Error(getDefaultI18n().t("error.unknownBackend", {
4405
+ throw new Error(this.i18n().t("error.unknownBackend", {
4366
4406
  backend: String(backend)
4367
4407
  }));
4368
4408
  }
4369
4409
  } catch (error) {
4370
4410
  this.state.lastError = error instanceof Error ? error : new Error(String(error));
4371
4411
  if (this.config.fallbackBackend && this.config.fallbackBackend !== backend) {
4372
- console.warn(getDefaultI18n().t("log.unifiedAgent.fallback", {
4412
+ console.warn(this.i18n().t("log.unifiedAgent.fallback", {
4373
4413
  backend: String(backend),
4374
4414
  fallback: String(this.config.fallbackBackend)
4375
4415
  }));
@@ -4386,13 +4426,13 @@ class UnifiedAgent {
4386
4426
  const config = this.config.config;
4387
4427
  this.provider = new ClaudeAgentSDKProvider2(config ?? {});
4388
4428
  if (!this.provider.isAvailable()) {
4389
- throw new Error(getDefaultI18n().t("error.claudeSdk.notAvailable"));
4429
+ throw new Error(this.i18n().t("error.claudeSdk.notAvailable"));
4390
4430
  }
4391
4431
  this.context = await this.provider.createContext(this.spec);
4392
4432
  this.state.isReady = true;
4393
4433
  } catch (error) {
4394
4434
  if (error.code === "MODULE_NOT_FOUND") {
4395
- throw new Error(getDefaultI18n().t("error.claudeSdk.notInstalled"));
4435
+ throw new Error(this.i18n().t("error.claudeSdk.notInstalled"));
4396
4436
  }
4397
4437
  throw error;
4398
4438
  }
@@ -4403,13 +4443,13 @@ class UnifiedAgent {
4403
4443
  const config = this.config.config;
4404
4444
  this.provider = new OpenCodeSDKProvider2(config ?? {});
4405
4445
  if (!this.provider.isAvailable()) {
4406
- throw new Error(getDefaultI18n().t("error.opencodeSdk.notAvailable"));
4446
+ throw new Error(this.i18n().t("error.opencodeSdk.notAvailable"));
4407
4447
  }
4408
4448
  this.context = await this.provider.createContext(this.spec);
4409
4449
  this.state.isReady = true;
4410
4450
  } catch (error) {
4411
4451
  if (error.code === "MODULE_NOT_FOUND") {
4412
- throw new Error(getDefaultI18n().t("error.opencodeSdk.notInstalled"));
4452
+ throw new Error(this.i18n().t("error.opencodeSdk.notInstalled"));
4413
4453
  }
4414
4454
  throw error;
4415
4455
  }
@@ -4428,7 +4468,7 @@ class UnifiedAgent {
4428
4468
  case "opencode-sdk":
4429
4469
  return await this.runWithExternalProvider(message, options);
4430
4470
  default:
4431
- throw new Error(getDefaultI18n().t("error.unknownBackend", {
4471
+ throw new Error(this.i18n().t("error.unknownBackend", {
4432
4472
  backend: String(backend)
4433
4473
  }));
4434
4474
  }
@@ -4452,7 +4492,7 @@ class UnifiedAgent {
4452
4492
  }
4453
4493
  async runWithExternalProvider(message, options) {
4454
4494
  if (!this.provider || !this.context) {
4455
- throw new Error(getDefaultI18n().t("error.providerNotInitialized"));
4495
+ throw new Error(this.i18n().t("error.providerNotInitialized"));
4456
4496
  }
4457
4497
  const result = await this.provider.execute(this.context, {
4458
4498
  prompt: message,