@zhivex-ai/harness 1.4.0 → 1.4.1

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 (117) hide show
  1. package/CHANGELOG.md +29 -10
  2. package/README.md +7 -5
  3. package/SUPPORT.md +2 -2
  4. package/contracts/client-protocol-v1.schema.json +593 -0
  5. package/contracts/engine-api.json +156 -0
  6. package/contracts/public-api.json +12 -0
  7. package/contracts/stable-api-signatures.json +33 -33
  8. package/dist/acp-cli.js +54 -20
  9. package/dist/audit/index.d.ts +3 -0
  10. package/dist/audit/index.js +482 -0
  11. package/dist/audit/pack.d.ts +72 -0
  12. package/dist/audit-pack-e4vaq7np.js +532 -0
  13. package/dist/cli/arguments.d.ts +3 -1
  14. package/dist/cli/audit-pack.d.ts +24 -0
  15. package/dist/cli/cli-credentials.d.ts +6 -0
  16. package/dist/cli/cli-profiles.d.ts +4 -2
  17. package/dist/cli/node-engine.d.ts +2 -0
  18. package/dist/{cli-2h37qyvg.js → cli-1cf4dcnj.js} +245 -642
  19. package/dist/{cli-entry-w0hterjs.js → cli-entry-3s63zn4w.js} +40 -13
  20. package/dist/cli-entry-7f0cen32.js +9990 -0
  21. package/dist/cli-entry-a890x3kq.js +10348 -0
  22. package/dist/{cli-entry-20w6nh0k.js → cli-entry-hdtfef27.js} +439 -19
  23. package/dist/cli-entry-rgs6bxmy.js +484 -0
  24. package/dist/cli.js +27 -2
  25. package/dist/client/json-contracts.d.ts +4 -0
  26. package/dist/client/protocol.d.ts +133 -0
  27. package/dist/client/task-control-host.d.ts +400 -0
  28. package/dist/client/task-projection-host.d.ts +12 -0
  29. package/dist/client/task-projection.d.ts +168 -0
  30. package/dist/compat/code-support.js +28 -22
  31. package/dist/{config-qt69hkqj.js → config-r9fdhce6.js} +3 -3
  32. package/dist/{config-j9624t6t.js → config-vyajmksy.js} +1 -1
  33. package/dist/engine/acp.js +15 -11
  34. package/dist/engine/client.js +14 -10
  35. package/dist/engine/desktop-providers-v1.d.ts +2 -0
  36. package/dist/engine/desktop-providers-v1.js +23 -3
  37. package/dist/engine/desktop-state-v1.js +11 -8
  38. package/dist/engine/index.d.ts +3 -0
  39. package/dist/engine/index.js +101 -554
  40. package/dist/engine/mcp-stdio-v1.js +8 -6
  41. package/dist/engine/models.js +76 -4
  42. package/dist/engine/protocol.d.ts +2 -0
  43. package/dist/engine/protocol.js +110 -0
  44. package/dist/engine/service.js +15 -11
  45. package/dist/hostile-repository-demo.js +1095 -505
  46. package/dist/{index-937cb7y8.js → index-02pqtbbg.js} +559 -33
  47. package/dist/{index-pp474137.js → index-0zs2dz26.js} +766 -931
  48. package/dist/{index-8zjmnyw5.js → index-1265j7t2.js} +73 -6
  49. package/dist/index-4fx5f3k5.js +269 -0
  50. package/dist/{index-nmjdwd4p.js → index-4gt045j0.js} +109 -1
  51. package/dist/{index-6dft2vev.js → index-6599mpmy.js} +5 -3
  52. package/dist/{index-tfzta544.js → index-74kkpyqk.js} +9 -7
  53. package/dist/{index-61gthdz6.js → index-8sm2a1wa.js} +1 -1
  54. package/dist/index-c39197wq.js +552 -0
  55. package/dist/{index-5jhgatga.js → index-crta5wzv.js} +7 -6
  56. package/dist/{index-m34q25jj.js → index-d9zkmhz3.js} +143 -824
  57. package/dist/{index-pdmevfxv.js → index-dtb2c6ds.js} +5 -259
  58. package/dist/index-f6mqa5gk.js +1535 -0
  59. package/dist/index-j6zxnc8m.js +490 -0
  60. package/dist/{index-rkbf7dqg.js → index-mv8sb1ns.js} +5 -3
  61. package/dist/{index-xqxeypt5.js → index-mzydbzp8.js} +76 -4
  62. package/dist/{index-wg1sd3at.js → index-qfsrrnz6.js} +1 -1
  63. package/dist/{index-m82cfspw.js → index-sk3cap35.js} +877 -963
  64. package/dist/index-sstgcsr0.js +511 -0
  65. package/dist/index-wm9xeq1n.js +329 -0
  66. package/dist/index-xdbkcccf.js +719 -0
  67. package/dist/{index-s2k2edts.js → index-zxg4ve4j.js} +41 -1548
  68. package/dist/index.d.ts +3 -0
  69. package/dist/index.js +93 -77
  70. package/dist/internal/desktop/providers.d.ts +2 -0
  71. package/dist/models/catalog.d.ts +2 -0
  72. package/dist/persistence/sqlite-database.d.ts +1 -0
  73. package/dist/providers/azure-openai.d.ts +14 -0
  74. package/dist/providers/bedrock.d.ts +23 -0
  75. package/dist/providers/providers.d.ts +1 -1
  76. package/dist/runtime/durable-review-group.d.ts +33 -0
  77. package/dist/runtime/harness.d.ts +11 -0
  78. package/dist/runtime/run-interruption.d.ts +7 -0
  79. package/dist/runtime/shared-budget.d.ts +30 -0
  80. package/dist/runtime/task-continuity.d.ts +300 -77
  81. package/dist/service-cli.js +15 -11
  82. package/dist/{service-client-cli-fn54ev6w.js → service-client-cli-eqrdc9zq.js} +400 -305
  83. package/dist/verify-historical-migrations.js +1095 -505
  84. package/dist/zhx.js +27 -2
  85. package/docs/AUDIT_PACK.md +99 -0
  86. package/docs/AZURE_OPENAI.md +53 -0
  87. package/docs/BEDROCK.md +56 -0
  88. package/docs/CLI.md +15 -0
  89. package/docs/CLIENT_PROTOCOL.md +178 -0
  90. package/docs/CODE_RELEASE.md +31 -1
  91. package/docs/CODE_WEB_TASKS.md +116 -0
  92. package/docs/CONTEXT_ENGINEERING.md +59 -0
  93. package/docs/CREDENTIALS.md +21 -0
  94. package/docs/DURABLE_OPERATIONS.md +93 -1
  95. package/docs/ENGINE_API.md +5 -2
  96. package/docs/EXTENSIBILITY.md +2 -2
  97. package/docs/FIRST_USE.md +6 -6
  98. package/docs/MINIMUM_TASK_AUTHORITY.md +3 -3
  99. package/docs/PROJECT_MEMORY.md +1 -1
  100. package/docs/README.md +6 -1
  101. package/docs/STABILITY.md +3 -1
  102. package/docs/SUPPORT_MATRIX.md +1 -1
  103. package/docs/SUPPORT_MATRIX_1_1.md +1 -1
  104. package/docs/USAGE.md +3 -1
  105. package/docs/VERTEX.md +2 -2
  106. package/docs/WEB_LIMITS.md +4 -3
  107. package/docs/adr/0002-isolated-mcp-stdio.md +6 -3
  108. package/docs/support-matrix-1.1.json +3 -1
  109. package/docs/support-matrix.json +6 -4
  110. package/evaluations/code-task-ui.json +20 -0
  111. package/evaluations/representative-assembly-matrix.json +10 -1
  112. package/evaluations/task-projection.json +10 -0
  113. package/evaluations/task-recovery-lab.json +60 -0
  114. package/examples/README.md +3 -3
  115. package/package.json +23 -13
  116. package/dist/cli-entry-4ngptr62.js +0 -19900
  117. package/dist/index-m49jx72n.js +0 -220
@@ -1,6 +1,6 @@
1
1
  // src/providers/reasoning.ts
2
2
  import { z as z3 } from "zod";
3
- import { wrapLanguageModel as wrapLanguageModel6 } from "@zhivex-ai/core";
3
+ import { wrapLanguageModel as wrapLanguageModel8 } from "@zhivex-ai/core";
4
4
 
5
5
  // src/providers/anthropic-continuation.ts
6
6
  import { ValidationError, wrapLanguageModel } from "@zhivex-ai/core";
@@ -497,8 +497,293 @@ function providerBody(value) {
497
497
  }
498
498
  }
499
499
 
500
- // src/providers/qwen-hosted-policy.ts
500
+ // src/providers/azure-openai.ts
501
+ import { createAzureOpenAI } from "@zhivex-ai/azure-openai";
501
502
  import { wrapLanguageModel as wrapLanguageModel3 } from "@zhivex-ai/core";
503
+ var API_VERSION = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
504
+ var DEPLOYMENT_NAME = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
505
+ var MODEL_ID = /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,159}$/;
506
+ function azureOpenAIEndpoint(env) {
507
+ const value = env.AZURE_OPENAI_ENDPOINT?.trim() ?? "";
508
+ if (!value)
509
+ throw new Error("Azure OpenAI requires AZURE_OPENAI_ENDPOINT.");
510
+ let url;
511
+ try {
512
+ url = new URL(value);
513
+ } catch {
514
+ throw new Error("AZURE_OPENAI_ENDPOINT must be an https URL.");
515
+ }
516
+ if (url.protocol !== "https:" || url.username || url.password || url.hash || url.search) {
517
+ throw new Error("AZURE_OPENAI_ENDPOINT must be an https URL without credentials or a query.");
518
+ }
519
+ return url.toString().replace(/\/+$/, "");
520
+ }
521
+ function azureOpenAIApiVersion(env) {
522
+ const value = env.AZURE_OPENAI_API_VERSION?.trim() ?? "";
523
+ if (!value)
524
+ return;
525
+ if (!API_VERSION.test(value))
526
+ throw new Error("AZURE_OPENAI_API_VERSION is invalid.");
527
+ return value;
528
+ }
529
+ function azureOpenAIDeployments(env) {
530
+ const raw = env.AZURE_OPENAI_DEPLOYMENTS?.trim() ?? "";
531
+ if (!raw)
532
+ return Object.freeze({});
533
+ if (raw.length > 8192)
534
+ throw new Error("AZURE_OPENAI_DEPLOYMENTS is too large.");
535
+ let parsed;
536
+ try {
537
+ parsed = JSON.parse(raw);
538
+ } catch {
539
+ throw new Error("AZURE_OPENAI_DEPLOYMENTS must be a JSON object.");
540
+ }
541
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
542
+ throw new Error("AZURE_OPENAI_DEPLOYMENTS must be a JSON object.");
543
+ }
544
+ const entries = Object.entries(parsed);
545
+ if (entries.length > 32)
546
+ throw new Error("AZURE_OPENAI_DEPLOYMENTS lists too many deployments.");
547
+ const deployments = {};
548
+ for (const [name, value] of entries) {
549
+ if (!DEPLOYMENT_NAME.test(name))
550
+ throw new Error("AZURE_OPENAI_DEPLOYMENTS contains an invalid deployment name.");
551
+ const model = typeof value === "string" ? value : value && typeof value === "object" && !Array.isArray(value) && typeof value.model === "string" ? value.model : "";
552
+ const normalized = model.trim();
553
+ if (!MODEL_ID.test(normalized))
554
+ throw new Error("AZURE_OPENAI_DEPLOYMENTS contains an invalid base model.");
555
+ deployments[name] = Object.freeze({ model: normalized });
556
+ }
557
+ return Object.freeze(deployments);
558
+ }
559
+ function azureOpenAIConfigured(env) {
560
+ try {
561
+ azureOpenAIEndpoint(env);
562
+ azureOpenAIApiVersion(env);
563
+ azureOpenAIDeployments(env);
564
+ return Boolean(env.AZURE_OPENAI_API_KEY?.trim());
565
+ } catch {
566
+ return false;
567
+ }
568
+ }
569
+ function createAzureOpenAIModel(model, env) {
570
+ const endpoint = azureOpenAIEndpoint(env);
571
+ const apiVersion = azureOpenAIApiVersion(env);
572
+ const deployments = azureOpenAIDeployments(env);
573
+ const apiKey = env.AZURE_OPENAI_API_KEY?.trim();
574
+ if (!apiKey)
575
+ throw new Error("Missing credentials for azure-openai. Set AZURE_OPENAI_API_KEY in the environment.");
576
+ const settings = {
577
+ apiKey,
578
+ endpoint,
579
+ ...apiVersion ? { apiVersion } : {},
580
+ ...Object.keys(deployments).length ? { deployments } : {}
581
+ };
582
+ const azure = apiVersion ? createAzureOpenAI(settings) : withoutProcessEnv(["AZURE_OPENAI_API_VERSION"], () => createAzureOpenAI(settings));
583
+ const deployed = sanitizeAzureModel(azure(model), apiKey);
584
+ const baseModel = deployments[model]?.model;
585
+ if (!baseModel || baseModel === model)
586
+ return deployed;
587
+ return withBaseModelCapabilities(deployed, azure(baseModel));
588
+ }
589
+ function withoutProcessEnv(names, run) {
590
+ const saved = new Map;
591
+ for (const name of names) {
592
+ saved.set(name, process.env[name]);
593
+ delete process.env[name];
594
+ }
595
+ try {
596
+ return run();
597
+ } finally {
598
+ for (const [name, value] of saved) {
599
+ if (value === undefined)
600
+ delete process.env[name];
601
+ else
602
+ process.env[name] = value;
603
+ }
604
+ }
605
+ }
606
+ function withBaseModelCapabilities(deployed, reference) {
607
+ return new Proxy(deployed, {
608
+ get(target, property, receiver) {
609
+ if (property === "capabilities")
610
+ return reference.capabilities;
611
+ const value = Reflect.get(target, property, receiver);
612
+ return typeof value === "function" ? value.bind(target) : value;
613
+ }
614
+ });
615
+ }
616
+ function sanitizeAzureModel(model, secret) {
617
+ const clean = (error) => {
618
+ if (error instanceof Error && error.name === "AbortError") {
619
+ return new DOMException("Azure OpenAI request cancelled.", "AbortError");
620
+ }
621
+ const record = error && typeof error === "object" ? error : {};
622
+ const safe = new Error("Azure OpenAI request failed. Check the endpoint, deployment, and credentials.");
623
+ if (secret && safe.message.includes(secret))
624
+ safe.message = safe.message.split(secret).join("[REDACTED]");
625
+ if (typeof record.status === "number")
626
+ Object.assign(safe, { status: record.status });
627
+ if (typeof record.retryable === "boolean")
628
+ Object.assign(safe, { retryable: record.retryable });
629
+ return safe;
630
+ };
631
+ return wrapLanguageModel3(model, [{
632
+ name: "harness-azure-openai-sanitized-errors",
633
+ async wrapGenerate(_context, next) {
634
+ try {
635
+ return await next();
636
+ } catch (error) {
637
+ throw clean(error);
638
+ }
639
+ },
640
+ async wrapStream(_context, next) {
641
+ let stream;
642
+ try {
643
+ stream = await next();
644
+ } catch (error) {
645
+ throw clean(error);
646
+ }
647
+ return async function* () {
648
+ try {
649
+ for await (const event of stream) {
650
+ if (event.type === "error")
651
+ throw clean(event.error);
652
+ yield event;
653
+ }
654
+ } catch (error) {
655
+ throw clean(error);
656
+ }
657
+ }();
658
+ }
659
+ }]);
660
+ }
661
+
662
+ // src/providers/bedrock.ts
663
+ import { createBedrock } from "@zhivex-ai/bedrock";
664
+ import { wrapLanguageModel as wrapLanguageModel4 } from "@zhivex-ai/core";
665
+ var REGION = /^[a-z]{2}(?:-[a-z0-9]+){1,3}$/;
666
+ function bedrockRuntime(env) {
667
+ const value = env.BEDROCK_RUNTIME?.trim() ?? "";
668
+ if (!value || value === "converse")
669
+ return "converse";
670
+ if (value === "openai")
671
+ return "openai";
672
+ throw new Error("BEDROCK_RUNTIME must be converse or openai.");
673
+ }
674
+ function bedrockRegion(env) {
675
+ const region = env.AWS_REGION?.trim() || env.AWS_DEFAULT_REGION?.trim() || "";
676
+ if (!REGION.test(region)) {
677
+ throw new Error("Bedrock requires a valid AWS_REGION or AWS_DEFAULT_REGION.");
678
+ }
679
+ return region;
680
+ }
681
+ function bedrockOpenAIBaseURL(env) {
682
+ const baseURL = env.BEDROCK_OPENAI_BASE_URL?.trim() ?? "";
683
+ if (!baseURL)
684
+ throw new Error("Bedrock OpenAI-compatible runtime requires BEDROCK_OPENAI_BASE_URL.");
685
+ let url;
686
+ try {
687
+ url = new URL(baseURL);
688
+ } catch {
689
+ throw new Error("BEDROCK_OPENAI_BASE_URL must be an https URL.");
690
+ }
691
+ if (url.protocol !== "https:" || url.username || url.password || url.hash) {
692
+ throw new Error("BEDROCK_OPENAI_BASE_URL must be an https URL without credentials.");
693
+ }
694
+ return url.toString().replace(/\/+$/, "");
695
+ }
696
+ function openAIRoute(env) {
697
+ const apiKey = env.BEDROCK_API_KEY?.trim() || env.AWS_BEARER_TOKEN_BEDROCK?.trim() || "";
698
+ if (!apiKey) {
699
+ throw new Error("Bedrock OpenAI-compatible runtime requires BEDROCK_API_KEY or AWS_BEARER_TOKEN_BEDROCK.");
700
+ }
701
+ return { apiKey, baseURL: bedrockOpenAIBaseURL(env) };
702
+ }
703
+ function bedrockConfigured(env) {
704
+ try {
705
+ if (bedrockRuntime(env) === "openai") {
706
+ openAIRoute(env);
707
+ return true;
708
+ }
709
+ bedrockRegion(env);
710
+ return true;
711
+ } catch {
712
+ return false;
713
+ }
714
+ }
715
+ function createBedrockModel(model, env) {
716
+ const runtime = bedrockRuntime(env);
717
+ if (runtime === "openai") {
718
+ const route = openAIRoute(env);
719
+ return sanitizeBedrockModel(createBedrock({
720
+ runtime: "openai",
721
+ apiKey: route.apiKey,
722
+ baseURL: route.baseURL
723
+ })(model), [route.apiKey]);
724
+ }
725
+ const region = bedrockRegion(env);
726
+ const bearer = env.AWS_BEARER_TOKEN_BEDROCK?.trim();
727
+ const accessKeyId = env.AWS_ACCESS_KEY_ID?.trim();
728
+ const secretAccessKey = env.AWS_SECRET_ACCESS_KEY?.trim();
729
+ const sessionToken = env.AWS_SESSION_TOKEN?.trim();
730
+ const staticCredentials = !bearer && accessKeyId && secretAccessKey ? { accessKeyId, secretAccessKey, ...sessionToken ? { sessionToken } : {} } : undefined;
731
+ return sanitizeBedrockModel(createBedrock({
732
+ region,
733
+ ...bearer ? { apiKey: bearer } : {},
734
+ ...staticCredentials ? { credentials: staticCredentials } : {}
735
+ })(model), [bearer, secretAccessKey, sessionToken].filter((value) => Boolean(value)));
736
+ }
737
+ function sanitizeBedrockModel(model, secrets) {
738
+ const clean = (error) => {
739
+ if (error instanceof Error && error.name === "AbortError") {
740
+ return new DOMException("Bedrock request cancelled.", "AbortError");
741
+ }
742
+ const record = error && typeof error === "object" ? error : {};
743
+ const safe = new Error("Bedrock request failed. Check region, model access, and credentials.");
744
+ if (typeof record.status === "number")
745
+ Object.assign(safe, { status: record.status });
746
+ if (typeof record.retryable === "boolean")
747
+ Object.assign(safe, { retryable: record.retryable });
748
+ for (const secret of secrets) {
749
+ if (secret && safe.message.includes(secret))
750
+ safe.message = safe.message.split(secret).join("[REDACTED]");
751
+ }
752
+ return safe;
753
+ };
754
+ return wrapLanguageModel4(model, [{
755
+ name: "harness-bedrock-sanitized-errors",
756
+ async wrapGenerate(_context, next) {
757
+ try {
758
+ return await next();
759
+ } catch (error) {
760
+ throw clean(error);
761
+ }
762
+ },
763
+ async wrapStream(_context, next) {
764
+ let stream;
765
+ try {
766
+ stream = await next();
767
+ } catch (error) {
768
+ throw clean(error);
769
+ }
770
+ return async function* () {
771
+ try {
772
+ for await (const event of stream) {
773
+ if (event.type === "error")
774
+ throw clean(event.error);
775
+ yield event;
776
+ }
777
+ } catch (error) {
778
+ throw clean(error);
779
+ }
780
+ }();
781
+ }
782
+ }]);
783
+ }
784
+
785
+ // src/providers/qwen-hosted-policy.ts
786
+ import { wrapLanguageModel as wrapLanguageModel5 } from "@zhivex-ai/core";
502
787
  function withQwenHostedPolicy(model) {
503
788
  if (model.modelId !== "kimi-k3")
504
789
  return model;
@@ -511,7 +796,7 @@ function withQwenHostedPolicy(model) {
511
796
  }
512
797
  input.providerOptions = { ...options, apiMode: "chat", enable_thinking: true };
513
798
  };
514
- const wrapped = wrapLanguageModel3(model, [{
799
+ const wrapped = wrapLanguageModel5(model, [{
515
800
  name: "harness-kimi-k3-chat-thinking-v1",
516
801
  async wrapGenerate(context, next) {
517
802
  prepare(context.input);
@@ -593,7 +878,7 @@ var createMetaContinuationFetch = (fetcher = fetch, backoff = [1000, 2000]) => {
593
878
  };
594
879
 
595
880
  // src/providers/meta-replay.ts
596
- import { wrapLanguageModel as wrapLanguageModel4 } from "@zhivex-ai/core";
881
+ import { wrapLanguageModel as wrapLanguageModel6 } from "@zhivex-ai/core";
597
882
  import { withTimeoutSignal } from "@zhivex-ai/core/provider";
598
883
  import { createMeta } from "@zhivex-ai/meta";
599
884
  var replayPlan = (messages) => {
@@ -660,7 +945,7 @@ var createMetaReplayModel = (options, modelId) => {
660
945
  } }
661
946
  };
662
947
  };
663
- return wrapLanguageModel4(createMeta(options)(modelId), [{
948
+ return wrapLanguageModel6(createMeta(options)(modelId), [{
664
949
  name: "harness-meta-stateless-replay-v1",
665
950
  async wrapGenerate({ input }) {
666
951
  const prepared = prepare(input);
@@ -752,7 +1037,7 @@ import { z as z2 } from "zod";
752
1037
  // src/models/catalog.json
753
1038
  var catalog_default = {
754
1039
  schemaVersion: 1,
755
- revision: "2026-09-29-vertex",
1040
+ revision: "2026-10-15-bedrock-azure",
756
1041
  providers: [
757
1042
  {
758
1043
  id: "openai",
@@ -1517,6 +1802,78 @@ var catalog_default = {
1517
1802
  reason: "Provisional Vertex route; availability depends on project, region and IAM. No live certification."
1518
1803
  }
1519
1804
  ]
1805
+ },
1806
+ {
1807
+ id: "bedrock",
1808
+ defaultModel: "anthropic.claude-haiku-5-5",
1809
+ models: [
1810
+ {
1811
+ id: "anthropic.claude-haiku-5-5",
1812
+ name: "Claude Haiku 5.5 (Bedrock)",
1813
+ group: "primary",
1814
+ order: 0,
1815
+ lifecycle: "unknown",
1816
+ validation: "unverified",
1817
+ capabilities: ["chat", "tools"],
1818
+ reason: "Provisional Bedrock Converse route. Account access, region, and live Harness certification are not verified. No prices or context limits are inferred."
1819
+ },
1820
+ {
1821
+ id: "anthropic.claude-sonnet-5-5",
1822
+ name: "Claude Sonnet 5.5 (Bedrock)",
1823
+ group: "other",
1824
+ order: 1,
1825
+ lifecycle: "unknown",
1826
+ validation: "unverified",
1827
+ capabilities: ["chat", "tools"],
1828
+ reason: "Provisional Bedrock model id. Availability depends on the account and region. No live certification."
1829
+ },
1830
+ {
1831
+ id: "amazon.nova-2-lite-v1:0",
1832
+ name: "Amazon Nova 2 Lite (Bedrock)",
1833
+ group: "other",
1834
+ order: 2,
1835
+ lifecycle: "unknown",
1836
+ validation: "unverified",
1837
+ capabilities: ["chat", "tools"],
1838
+ reason: "Provisional Bedrock model id. Availability depends on the account and region. No live certification."
1839
+ }
1840
+ ]
1841
+ },
1842
+ {
1843
+ id: "azure-openai",
1844
+ defaultModel: "gpt-5.4",
1845
+ models: [
1846
+ {
1847
+ id: "gpt-5.4",
1848
+ name: "GPT-5.4 (Azure OpenAI)",
1849
+ group: "primary",
1850
+ order: 0,
1851
+ lifecycle: "unknown",
1852
+ validation: "unverified",
1853
+ capabilities: ["chat", "tools"],
1854
+ reason: "Provisional Azure OpenAI route. Deployment name, API version, and live Harness certification are not verified. No prices are copied from the OpenAI API."
1855
+ },
1856
+ {
1857
+ id: "gpt-5",
1858
+ name: "GPT-5 (Azure OpenAI)",
1859
+ group: "other",
1860
+ order: 1,
1861
+ lifecycle: "unknown",
1862
+ validation: "unverified",
1863
+ capabilities: ["chat", "tools"],
1864
+ reason: "Provisional Azure OpenAI model id. Use AZURE_OPENAI_DEPLOYMENTS when the deployment name differs. No live certification."
1865
+ },
1866
+ {
1867
+ id: "gpt-6-astra",
1868
+ name: "GPT-6 Astra (Azure OpenAI)",
1869
+ group: "other",
1870
+ order: 2,
1871
+ lifecycle: "unknown",
1872
+ validation: "unverified",
1873
+ capabilities: ["chat", "tools"],
1874
+ reason: "Provisional Azure OpenAI model id. Account rollout and deployment availability are not verified. No live certification."
1875
+ }
1876
+ ]
1520
1877
  }
1521
1878
  ]
1522
1879
  };
@@ -1579,13 +1936,13 @@ var modelCatalogSchema = z2.object({
1579
1936
  schemaVersion: z2.literal(1),
1580
1937
  revision: z2.string().min(1).max(80).regex(/^[a-zA-Z0-9._-]+$/),
1581
1938
  providers: z2.array(z2.object({
1582
- id: z2.enum(["openai", "qwen", "gemini", "meta", "anthropic", "vertex"]),
1939
+ id: z2.enum(["openai", "qwen", "gemini", "meta", "anthropic", "vertex", "bedrock", "azure-openai"]),
1583
1940
  defaultModel: modelId,
1584
1941
  models: z2.array(catalogModelSchema).min(1).max(500)
1585
- }).strict()).length(6)
1942
+ }).strict()).length(8)
1586
1943
  }).strict().superRefine((catalog, ctx) => {
1587
1944
  const invalid = (message) => ctx.addIssue({ code: "custom", message });
1588
- if (new Set(catalog.providers.map((p) => p.id)).size !== 6)
1945
+ if (new Set(catalog.providers.map((p) => p.id)).size !== 8)
1589
1946
  invalid("Duplicate providers");
1590
1947
  for (const provider of catalog.providers) {
1591
1948
  const ids = new Set(provider.models.map((m) => m.id));
@@ -1637,13 +1994,13 @@ function modelDescription(model) {
1637
1994
  // src/providers/providers.ts
1638
1995
  import { createHash } from "node:crypto";
1639
1996
  import {
1640
- wrapLanguageModel as wrapLanguageModel5
1997
+ wrapLanguageModel as wrapLanguageModel7
1641
1998
  } from "@zhivex-ai/core";
1642
1999
  import { createAnthropic } from "@zhivex-ai/anthropic";
1643
2000
  import { createGemini } from "@zhivex-ai/gemini";
1644
2001
  import { createOpenAI } from "@zhivex-ai/openai";
1645
2002
  import { createQwen } from "@zhivex-ai/qwen";
1646
- var PROVIDERS = ["meta", "qwen", "openai", "gemini", "anthropic", "vertex"];
2003
+ var PROVIDERS = ["meta", "qwen", "openai", "gemini", "anthropic", "vertex", "bedrock", "azure-openai"];
1647
2004
  var HARNESS_PROVIDER_CAPABILITIES = [
1648
2005
  "streaming",
1649
2006
  "tool-calling",
@@ -1862,13 +2219,13 @@ var createProviderRegistry = (registrations) => {
1862
2219
  const credentials = Object.freeze(registration.descriptor.credentialNames.map((name) => Object.freeze({ name, present: Boolean(env[name]?.trim()) })));
1863
2220
  return Object.freeze({
1864
2221
  ...registration.descriptor,
1865
- configured: registration.descriptor.id === "vertex" ? vertexConfigured(env) : credentials.length === 0 || credentials.some((credential) => credential.present),
2222
+ configured: builtinConfigured(registration.descriptor.id, env, credentials),
1866
2223
  credentials,
1867
2224
  configuration: providerConfiguration(registration.diagnostics, env)
1868
2225
  });
1869
2226
  })),
1870
2227
  transportFingerprint: (env = process.env) => {
1871
- const transport = frozenRegistrations.filter((registration) => (registration.descriptor.id !== "anthropic" || Boolean(env.ANTHROPIC_BASE_URL?.trim())) && (registration.descriptor.id !== "vertex" || VERTEX_ENVIRONMENT.some((name) => Boolean(env[name]?.trim())))).map((registration) => {
2228
+ const transport = frozenRegistrations.filter((registration) => includeTransport(registration.descriptor.id, env)).map((registration) => {
1872
2229
  const names = [
1873
2230
  registration.diagnostics.endpointEnvironmentVariable,
1874
2231
  ...(registration.diagnostics.presence ?? []).map((entry) => entry.environmentVariable),
@@ -1888,6 +2245,27 @@ var createProviderRegistry = (registrations) => {
1888
2245
  });
1889
2246
  return registry;
1890
2247
  };
2248
+ var environmentPresent = (env, names) => names.some((name) => Boolean(env[name]?.trim()));
2249
+ var builtinConfigured = (id, env, credentials) => {
2250
+ if (id === "vertex")
2251
+ return vertexConfigured(env);
2252
+ if (id === "bedrock")
2253
+ return bedrockConfigured(env);
2254
+ if (id === "azure-openai")
2255
+ return azureOpenAIConfigured(env);
2256
+ return credentials.length === 0 || credentials.some((credential) => credential.present);
2257
+ };
2258
+ var includeTransport = (id, env) => {
2259
+ if (id === "anthropic")
2260
+ return Boolean(env.ANTHROPIC_BASE_URL?.trim());
2261
+ if (id === "vertex")
2262
+ return environmentPresent(env, VERTEX_ENVIRONMENT);
2263
+ if (id === "bedrock")
2264
+ return bedrockConfigured(env);
2265
+ if (id === "azure-openai")
2266
+ return azureOpenAIConfigured(env);
2267
+ return true;
2268
+ };
1891
2269
  var optionalQwenRegion = (value) => {
1892
2270
  if (!value) {
1893
2271
  return;
@@ -1962,12 +2340,12 @@ var normalizeStreamToolCallIds = async function* (model, input, events) {
1962
2340
  };
1963
2341
  }
1964
2342
  };
1965
- var withQwenDurableToolCallIds = (model) => wrapLanguageModel5(model, [{
2343
+ var withQwenDurableToolCallIds = (model) => wrapLanguageModel7(model, [{
1966
2344
  name: "harness-qwen-durable-tool-call-ids",
1967
2345
  wrapGenerate: async ({ input }, next) => normalizeGenerateToolCallIds(model, input, await next()),
1968
2346
  wrapStream: async ({ input }, next) => normalizeStreamToolCallIds(model, input, await next())
1969
2347
  }]);
1970
- var withOpenAIToolResultEnvelopes = (model) => wrapLanguageModel5(model, [{
2348
+ var withOpenAIToolResultEnvelopes = (model) => wrapLanguageModel7(model, [{
1971
2349
  name: "harness-openai-tool-result-envelopes-v1",
1972
2350
  async wrapGenerate({ input }, next) {
1973
2351
  input.toolResultFormat = "envelope";
@@ -1978,7 +2356,7 @@ var withOpenAIToolResultEnvelopes = (model) => wrapLanguageModel5(model, [{
1978
2356
  return next();
1979
2357
  }
1980
2358
  }]);
1981
- var withMetaResponses = (model) => wrapLanguageModel5(model, [{
2359
+ var withMetaResponses = (model) => wrapLanguageModel7(model, [{
1982
2360
  name: "harness-meta-responses-v1",
1983
2361
  async wrapGenerate({ input }, next) {
1984
2362
  input.providerOptions = { ...input.providerOptions, apiMode: "responses" };
@@ -2117,6 +2495,48 @@ var BUILTIN_PROVIDER_REGISTRATIONS = Object.freeze([
2117
2495
  ...baseURL ? { baseURL } : {}
2118
2496
  })(model);
2119
2497
  }
2498
+ },
2499
+ {
2500
+ descriptor: {
2501
+ id: "bedrock",
2502
+ name: "Amazon Bedrock",
2503
+ defaultModel: bundledDefaultModel("bedrock"),
2504
+ credentialNames: ["BEDROCK_API_KEY", "AWS_BEARER_TOKEN_BEDROCK"],
2505
+ capabilities: HARNESS_PROVIDER_CAPABILITIES,
2506
+ support: "provisional"
2507
+ },
2508
+ diagnostics: {
2509
+ endpointEnvironmentVariable: "BEDROCK_OPENAI_BASE_URL",
2510
+ presence: [
2511
+ { key: "region", environmentVariable: "AWS_REGION" },
2512
+ { key: "defaultRegion", environmentVariable: "AWS_DEFAULT_REGION" },
2513
+ { key: "profile", environmentVariable: "AWS_PROFILE" }
2514
+ ],
2515
+ enums: [{
2516
+ key: "runtime",
2517
+ environmentVariable: "BEDROCK_RUNTIME",
2518
+ allowedValues: ["converse", "openai"]
2519
+ }]
2520
+ },
2521
+ factory: ({ model, env }) => createBedrockModel(model, env)
2522
+ },
2523
+ {
2524
+ descriptor: {
2525
+ id: "azure-openai",
2526
+ name: "Azure OpenAI",
2527
+ defaultModel: bundledDefaultModel("azure-openai"),
2528
+ credentialNames: ["AZURE_OPENAI_API_KEY"],
2529
+ capabilities: HARNESS_PROVIDER_CAPABILITIES,
2530
+ support: "provisional"
2531
+ },
2532
+ diagnostics: {
2533
+ endpointEnvironmentVariable: "AZURE_OPENAI_ENDPOINT",
2534
+ presence: [
2535
+ { key: "apiVersion", environmentVariable: "AZURE_OPENAI_API_VERSION" },
2536
+ { key: "deployments", environmentVariable: "AZURE_OPENAI_DEPLOYMENTS" }
2537
+ ]
2538
+ },
2539
+ factory: ({ model, env }) => createAzureOpenAIModel(model, env)
2120
2540
  }
2121
2541
  ]);
2122
2542
  var DEFAULT_PROVIDER_REGISTRY = createProviderRegistry(BUILTIN_PROVIDER_REGISTRATIONS);
@@ -2137,7 +2557,7 @@ function withReasoningEffort(model, value) {
2137
2557
  return model;
2138
2558
  if (!supportedReasoningEfforts(model.capabilities).includes(value))
2139
2559
  throw new Error(`Reasoning effort ${value} is not declared for ${model.provider}/${model.modelId}. Use default or a supported level.`);
2140
- return wrapLanguageModel6(model, [{
2560
+ return wrapLanguageModel8(model, [{
2141
2561
  name: `harness-reasoning-${value}`,
2142
2562
  async wrapGenerate(context, next) {
2143
2563
  context.input.reasoning = { ...context.input.reasoning, effort: value };
@@ -2676,7 +3096,7 @@ var resolveHarnessConfig = (input = {}, registry = DEFAULT_PROVIDER_REGISTRY) =>
2676
3096
  var createProviderModel = (config, env = process.env, registry = DEFAULT_PROVIDER_REGISTRY) => {
2677
3097
  try {
2678
3098
  const model = registry.createModel(config, env);
2679
- return registry === DEFAULT_PROVIDER_REGISTRY && ["anthropic", "openai", "gemini", "vertex", "qwen"].includes(config.provider) ? markTaskTransportModel(model) : model;
3099
+ return registry === DEFAULT_PROVIDER_REGISTRY && ["anthropic", "openai", "gemini", "vertex", "qwen", "bedrock", "azure-openai"].includes(config.provider) ? markTaskTransportModel(model) : model;
2680
3100
  } catch (error) {
2681
3101
  throw new HarnessProviderError(`Provider ${config.provider} could not be initialized.`, {
2682
3102
  cause: error,
@@ -2685,4 +3105,4 @@ var createProviderModel = (config, env = process.env, registry = DEFAULT_PROVIDE
2685
3105
  }
2686
3106
  };
2687
3107
  var providerAvailability = (env = process.env, registry = DEFAULT_PROVIDER_REGISTRY) => registry.availability(env);
2688
- export { HARNESS_ERROR_CODES, HARNESS_ERROR_SCHEMA_VERSION, providerStreamDiagnostic, HarnessError, HarnessConfigError, HarnessWorkspaceError, HarnessStateConflictError, HarnessProviderError, HarnessExecutionError, harnessErrorDocument, normalizeHarnessError, vertexRoute, vertexConfigured, modelCatalogSchema, bundledModelCatalog, catalogModels, modelDescription, PROVIDERS, createProviderRegistry, BUILTIN_PROVIDER_REGISTRATIONS, DEFAULT_PROVIDER_REGISTRY, PROVIDER_DESCRIPTORS, reasoningEffortSchema, modelReasoningEfforts, withReasoningEffort, isTaskTransportModel, DEFAULT_ALLOWED_CHECKS, HARNESS_CONFIG_SCHEMA_VERSION, HARNESS_CONFIG_MIGRATABLE_SCHEMA_VERSIONS, HARNESS_STORE_BACKENDS, HARNESS_EXECUTION_BACKENDS, HARNESS_OCI_RUNTIMES, HARNESS_OCI_SHELL_MODES, HARNESS_EXECUTION_POLICY_VERSION, DEFAULT_OCI_EXECUTION, HARNESS_REQUIRED_CAPABILITIES, HARNESS_SUBAGENT_PROFILES, DEFAULT_HARNESS_MAX_STEPS, DEFAULT_HARNESS_BUDGET, DEFAULT_HARNESS_COMPACTION, DEFAULT_SUBAGENT_BUDGET, migrateHarnessConfigInput, defaultHarnessNamespace, parseProvider, providerDescriptor, resolveHarnessConfig, createProviderModel, providerAvailability };
3108
+ export { HARNESS_ERROR_CODES, HARNESS_ERROR_SCHEMA_VERSION, providerStreamDiagnostic, HarnessError, HarnessConfigError, HarnessWorkspaceError, HarnessStateConflictError, HarnessProviderError, HarnessExecutionError, harnessErrorDocument, normalizeHarnessError, vertexRoute, vertexConfigured, azureOpenAIEndpoint, azureOpenAIApiVersion, azureOpenAIDeployments, bedrockRuntime, bedrockRegion, bedrockOpenAIBaseURL, bedrockConfigured, modelCatalogSchema, bundledModelCatalog, catalogModels, modelDescription, PROVIDERS, createProviderRegistry, BUILTIN_PROVIDER_REGISTRATIONS, DEFAULT_PROVIDER_REGISTRY, PROVIDER_DESCRIPTORS, reasoningEffortSchema, modelReasoningEfforts, withReasoningEffort, isTaskTransportModel, DEFAULT_ALLOWED_CHECKS, HARNESS_CONFIG_SCHEMA_VERSION, HARNESS_CONFIG_MIGRATABLE_SCHEMA_VERSIONS, HARNESS_STORE_BACKENDS, HARNESS_EXECUTION_BACKENDS, HARNESS_OCI_RUNTIMES, HARNESS_OCI_SHELL_MODES, HARNESS_EXECUTION_POLICY_VERSION, DEFAULT_OCI_EXECUTION, HARNESS_REQUIRED_CAPABILITIES, HARNESS_SUBAGENT_PROFILES, DEFAULT_HARNESS_MAX_STEPS, DEFAULT_HARNESS_BUDGET, DEFAULT_HARNESS_COMPACTION, DEFAULT_SUBAGENT_BUDGET, migrateHarnessConfigInput, defaultHarnessNamespace, parseProvider, providerDescriptor, resolveHarnessConfig, createProviderModel, providerAvailability };