@contractspec/lib.ai-agent 2.4.0 → 2.5.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() {
@@ -4261,6 +4296,9 @@ class UnifiedAgent {
4261
4296
  messageCount: 0
4262
4297
  };
4263
4298
  }
4299
+ i18n(runtimeLocale) {
4300
+ return createAgentI18n(this.spec.locale, runtimeLocale ?? this.config.locale);
4301
+ }
4264
4302
  async initialize() {
4265
4303
  const backend = this.config.backend;
4266
4304
  try {
@@ -4275,14 +4313,14 @@ class UnifiedAgent {
4275
4313
  await this.initializeOpenCodeSDK();
4276
4314
  break;
4277
4315
  default:
4278
- throw new Error(getDefaultI18n().t("error.unknownBackend", {
4316
+ throw new Error(this.i18n().t("error.unknownBackend", {
4279
4317
  backend: String(backend)
4280
4318
  }));
4281
4319
  }
4282
4320
  } catch (error) {
4283
4321
  this.state.lastError = error instanceof Error ? error : new Error(String(error));
4284
4322
  if (this.config.fallbackBackend && this.config.fallbackBackend !== backend) {
4285
- console.warn(getDefaultI18n().t("log.unifiedAgent.fallback", {
4323
+ console.warn(this.i18n().t("log.unifiedAgent.fallback", {
4286
4324
  backend: String(backend),
4287
4325
  fallback: String(this.config.fallbackBackend)
4288
4326
  }));
@@ -4299,13 +4337,13 @@ class UnifiedAgent {
4299
4337
  const config = this.config.config;
4300
4338
  this.provider = new ClaudeAgentSDKProvider2(config ?? {});
4301
4339
  if (!this.provider.isAvailable()) {
4302
- throw new Error(getDefaultI18n().t("error.claudeSdk.notAvailable"));
4340
+ throw new Error(this.i18n().t("error.claudeSdk.notAvailable"));
4303
4341
  }
4304
4342
  this.context = await this.provider.createContext(this.spec);
4305
4343
  this.state.isReady = true;
4306
4344
  } catch (error) {
4307
4345
  if (error.code === "MODULE_NOT_FOUND") {
4308
- throw new Error(getDefaultI18n().t("error.claudeSdk.notInstalled"));
4346
+ throw new Error(this.i18n().t("error.claudeSdk.notInstalled"));
4309
4347
  }
4310
4348
  throw error;
4311
4349
  }
@@ -4316,13 +4354,13 @@ class UnifiedAgent {
4316
4354
  const config = this.config.config;
4317
4355
  this.provider = new OpenCodeSDKProvider2(config ?? {});
4318
4356
  if (!this.provider.isAvailable()) {
4319
- throw new Error(getDefaultI18n().t("error.opencodeSdk.notAvailable"));
4357
+ throw new Error(this.i18n().t("error.opencodeSdk.notAvailable"));
4320
4358
  }
4321
4359
  this.context = await this.provider.createContext(this.spec);
4322
4360
  this.state.isReady = true;
4323
4361
  } catch (error) {
4324
4362
  if (error.code === "MODULE_NOT_FOUND") {
4325
- throw new Error(getDefaultI18n().t("error.opencodeSdk.notInstalled"));
4363
+ throw new Error(this.i18n().t("error.opencodeSdk.notInstalled"));
4326
4364
  }
4327
4365
  throw error;
4328
4366
  }
@@ -4341,7 +4379,7 @@ class UnifiedAgent {
4341
4379
  case "opencode-sdk":
4342
4380
  return await this.runWithExternalProvider(message, options);
4343
4381
  default:
4344
- throw new Error(getDefaultI18n().t("error.unknownBackend", {
4382
+ throw new Error(this.i18n().t("error.unknownBackend", {
4345
4383
  backend: String(backend)
4346
4384
  }));
4347
4385
  }
@@ -4365,7 +4403,7 @@ class UnifiedAgent {
4365
4403
  }
4366
4404
  async runWithExternalProvider(message, options) {
4367
4405
  if (!this.provider || !this.context) {
4368
- throw new Error(getDefaultI18n().t("error.providerNotInitialized"));
4406
+ throw new Error(this.i18n().t("error.providerNotInitialized"));
4369
4407
  }
4370
4408
  const result = await this.provider.execute(this.context, {
4371
4409
  prompt: message,