@finalai/final-agent-provider 0.10.1 → 0.11.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 (159) hide show
  1. package/HOSTING.md +334 -245
  2. package/README.md +126 -40
  3. package/WORKSPACE-EGRESS.md +11 -11
  4. package/dist/modules/catalog.d.mts +9 -0
  5. package/dist/modules/catalog.mjs +21 -0
  6. package/dist/modules/catalog.mjs.map +7 -0
  7. package/dist/modules/harnesses/acp-agent.d.mts +4 -0
  8. package/dist/modules/harnesses/acp-agent.mjs +35 -0
  9. package/dist/modules/harnesses/acp-agent.mjs.map +7 -0
  10. package/dist/modules/harnesses/adapters.d.mts +7 -0
  11. package/dist/modules/harnesses/adapters.mjs +74 -0
  12. package/dist/modules/harnesses/adapters.mjs.map +7 -0
  13. package/dist/modules/harnesses/claude-code.d.mts +14 -0
  14. package/dist/modules/harnesses/claude-code.mjs +79 -0
  15. package/dist/modules/harnesses/claude-code.mjs.map +7 -0
  16. package/dist/modules/harnesses/codex.d.mts +12 -0
  17. package/dist/modules/harnesses/codex.mjs +90 -0
  18. package/dist/modules/harnesses/codex.mjs.map +7 -0
  19. package/dist/modules/harnesses/config-fields.d.mts +98 -57
  20. package/dist/modules/harnesses/config-fields.mjs +58 -35
  21. package/dist/modules/harnesses/config-fields.mjs.map +3 -3
  22. package/dist/modules/harnesses/definitions.d.mts +3 -0
  23. package/dist/modules/harnesses/definitions.mjs +21 -0
  24. package/dist/modules/harnesses/definitions.mjs.map +7 -0
  25. package/dist/modules/harnesses/fidelity.d.mts +1 -1
  26. package/dist/modules/harnesses/fidelity.mjs +17 -14
  27. package/dist/modules/harnesses/fidelity.mjs.map +2 -2
  28. package/dist/modules/harnesses/final.d.mts +12 -0
  29. package/dist/modules/harnesses/final.mjs +70 -0
  30. package/dist/modules/harnesses/final.mjs.map +7 -0
  31. package/dist/modules/harnesses/index.d.mts +13 -12
  32. package/dist/modules/harnesses/index.mjs +86 -45
  33. package/dist/modules/harnesses/index.mjs.map +3 -3
  34. package/dist/modules/harnesses/names.d.mts +43 -0
  35. package/dist/modules/harnesses/names.mjs +59 -0
  36. package/dist/modules/harnesses/names.mjs.map +7 -0
  37. package/dist/modules/harnesses/nanocode-claude.d.mts +18 -0
  38. package/dist/modules/harnesses/nanocode-claude.mjs +101 -0
  39. package/dist/modules/harnesses/nanocode-claude.mjs.map +7 -0
  40. package/dist/modules/harnesses/nanocode-codex.d.mts +13 -0
  41. package/dist/modules/harnesses/nanocode-codex.mjs +64 -0
  42. package/dist/modules/harnesses/nanocode-codex.mjs.map +7 -0
  43. package/dist/modules/harnesses/pi.d.mts +12 -0
  44. package/dist/modules/harnesses/pi.mjs +71 -0
  45. package/dist/modules/harnesses/pi.mjs.map +7 -0
  46. package/dist/modules/integrations.d.mts +9 -0
  47. package/dist/modules/integrations.mjs +29 -0
  48. package/dist/modules/integrations.mjs.map +7 -0
  49. package/dist/modules/provider/general.bundle.d.mts +1 -0
  50. package/dist/modules/provider/general.bundle.mjs +5 -0
  51. package/dist/modules/provider/general.bundle.mjs.map +7 -0
  52. package/dist/modules/provider/general.d.mts +11 -0
  53. package/dist/modules/provider/general.mjs +130 -0
  54. package/dist/modules/provider/general.mjs.map +7 -0
  55. package/dist/modules/provider/index.d.mts +3 -0
  56. package/dist/modules/provider/index.mjs +13 -0
  57. package/dist/modules/provider/index.mjs.map +7 -0
  58. package/dist/modules/sandboxes/access.d.mts +34 -0
  59. package/dist/modules/sandboxes/access.mjs +15 -0
  60. package/dist/modules/sandboxes/access.mjs.map +7 -0
  61. package/dist/modules/sandboxes/computer.d.mts +24 -51
  62. package/dist/modules/sandboxes/computer.mjs +523 -888
  63. package/dist/modules/sandboxes/computer.mjs.map +3 -3
  64. package/dist/modules/sandboxes/computers-api.d.mts +3 -2
  65. package/dist/modules/sandboxes/computers-api.mjs +2 -4
  66. package/dist/modules/sandboxes/computers-api.mjs.map +2 -2
  67. package/dist/modules/sandboxes/device-api.d.mts +4 -3
  68. package/dist/modules/sandboxes/device-api.mjs +2 -4
  69. package/dist/modules/sandboxes/device-api.mjs.map +2 -2
  70. package/dist/modules/sandboxes/device.d.mts +6 -6
  71. package/dist/modules/sandboxes/device.mjs +126 -121
  72. package/dist/modules/sandboxes/device.mjs.map +3 -3
  73. package/dist/modules/sandboxes/egress.d.mts +10 -9
  74. package/dist/modules/sandboxes/egress.mjs +73 -56
  75. package/dist/modules/sandboxes/egress.mjs.map +2 -2
  76. package/dist/modules/sandboxes/environment.d.mts +35 -269
  77. package/dist/modules/sandboxes/environment.mjs +27 -104
  78. package/dist/modules/sandboxes/environment.mjs.map +3 -3
  79. package/dist/modules/sandboxes/index.d.mts +9 -69
  80. package/dist/modules/sandboxes/index.mjs +35 -95
  81. package/dist/modules/sandboxes/index.mjs.map +3 -3
  82. package/dist/modules/sandboxes/local.d.mts +28 -0
  83. package/dist/modules/sandboxes/local.mjs +499 -0
  84. package/dist/modules/sandboxes/local.mjs.map +7 -0
  85. package/dist/modules/sandboxes/session.d.mts +0 -3
  86. package/dist/modules/sandboxes/session.mjs +2 -22
  87. package/dist/modules/sandboxes/session.mjs.map +2 -2
  88. package/dist/modules/sandboxes/testing/fake-machine.mjs +0 -28
  89. package/dist/modules/sandboxes/testing/fake-machine.mjs.map +2 -2
  90. package/package.json +76 -104
  91. package/dist/modules/connections.d.mts +0 -11
  92. package/dist/modules/connections.mjs +0 -16
  93. package/dist/modules/connections.mjs.map +0 -7
  94. package/dist/modules/harnesses/acp-describe.d.mts +0 -20
  95. package/dist/modules/harnesses/acp-describe.mjs +0 -110
  96. package/dist/modules/harnesses/acp-describe.mjs.map +0 -7
  97. package/dist/modules/harnesses/local-stdio.d.mts +0 -47
  98. package/dist/modules/harnesses/local-stdio.mjs +0 -41
  99. package/dist/modules/harnesses/local-stdio.mjs.map +0 -7
  100. package/dist/modules/harnesses/remote-acp.d.mts +0 -76
  101. package/dist/modules/harnesses/remote-acp.mjs +0 -83
  102. package/dist/modules/harnesses/remote-acp.mjs.map +0 -7
  103. package/dist/modules/harnesses/remote-claude-code.d.mts +0 -88
  104. package/dist/modules/harnesses/remote-claude-code.mjs +0 -113
  105. package/dist/modules/harnesses/remote-claude-code.mjs.map +0 -7
  106. package/dist/modules/harnesses/remote-client-tls.d.mts +0 -35
  107. package/dist/modules/harnesses/remote-client-tls.mjs +0 -37
  108. package/dist/modules/harnesses/remote-client-tls.mjs.map +0 -7
  109. package/dist/modules/harnesses/remote-codex.d.mts +0 -98
  110. package/dist/modules/harnesses/remote-codex.mjs +0 -128
  111. package/dist/modules/harnesses/remote-codex.mjs.map +0 -7
  112. package/dist/modules/harnesses/remote-pi.d.mts +0 -78
  113. package/dist/modules/harnesses/remote-pi.mjs +0 -104
  114. package/dist/modules/harnesses/remote-pi.mjs.map +0 -7
  115. package/dist/modules/harnesses/remote-url.d.mts +0 -5
  116. package/dist/modules/harnesses/remote-url.mjs +0 -19
  117. package/dist/modules/harnesses/remote-url.mjs.map +0 -7
  118. package/dist/modules/harnesses/serverless-final.d.mts +0 -63
  119. package/dist/modules/harnesses/serverless-final.mjs +0 -88
  120. package/dist/modules/harnesses/serverless-final.mjs.map +0 -7
  121. package/dist/modules/harnesses/serverless-nanocode-claude.d.mts +0 -64
  122. package/dist/modules/harnesses/serverless-nanocode-claude.mjs +0 -105
  123. package/dist/modules/harnesses/serverless-nanocode-claude.mjs.map +0 -7
  124. package/dist/modules/harnesses/serverless-nanocode-codex.d.mts +0 -66
  125. package/dist/modules/harnesses/serverless-nanocode-codex.mjs +0 -113
  126. package/dist/modules/harnesses/serverless-nanocode-codex.mjs.map +0 -7
  127. package/dist/modules/harnesses/serverless-pi.d.mts +0 -64
  128. package/dist/modules/harnesses/serverless-pi.mjs +0 -98
  129. package/dist/modules/harnesses/serverless-pi.mjs.map +0 -7
  130. package/dist/modules/runtime/index.d.mts +0 -7
  131. package/dist/modules/runtime/index.mjs +0 -18
  132. package/dist/modules/runtime/index.mjs.map +0 -7
  133. package/dist/modules/runtime/local-stdio.d.mts +0 -10
  134. package/dist/modules/runtime/local-stdio.mjs +0 -106
  135. package/dist/modules/runtime/local-stdio.mjs.map +0 -7
  136. package/dist/modules/runtime/remote-acp.d.mts +0 -16
  137. package/dist/modules/runtime/remote-acp.mjs +0 -152
  138. package/dist/modules/runtime/remote-acp.mjs.map +0 -7
  139. package/dist/modules/runtime/remote-claude-code.d.mts +0 -5
  140. package/dist/modules/runtime/remote-claude-code.mjs +0 -47
  141. package/dist/modules/runtime/remote-claude-code.mjs.map +0 -7
  142. package/dist/modules/runtime/remote-codex.d.mts +0 -5
  143. package/dist/modules/runtime/remote-codex.mjs +0 -47
  144. package/dist/modules/runtime/remote-codex.mjs.map +0 -7
  145. package/dist/modules/runtime/remote-host.d.mts +0 -127
  146. package/dist/modules/runtime/remote-host.mjs +0 -387
  147. package/dist/modules/runtime/remote-host.mjs.map +0 -7
  148. package/dist/modules/runtime/remote-pi.d.mts +0 -5
  149. package/dist/modules/runtime/remote-pi.mjs +0 -44
  150. package/dist/modules/runtime/remote-pi.mjs.map +0 -7
  151. package/dist/modules/sandboxes/guide.d.mts +0 -35
  152. package/dist/modules/sandboxes/guide.mjs +0 -119
  153. package/dist/modules/sandboxes/guide.mjs.map +0 -7
  154. package/dist/modules/sandboxes/workspace-setup.d.mts +0 -42
  155. package/dist/modules/sandboxes/workspace-setup.mjs +0 -242
  156. package/dist/modules/sandboxes/workspace-setup.mjs.map +0 -7
  157. package/dist/modules/testing/harness.d.mts +0 -9
  158. package/dist/modules/testing/harness.mjs +0 -123
  159. package/dist/modules/testing/harness.mjs.map +0 -7
@@ -0,0 +1,18 @@
1
+ import { type HarnessDefinitionIface, type HarnessEnvironmentIface, type HarnessSettingsIface, type JsonSchema } from '@finalai/agent-provider';
2
+ import { ApprovalsReviewer, ReasoningLevel, type InferenceInput, type PermissionInput } from "./config-fields.mjs";
3
+ export declare const CLAUDE_REASONING_LEVELS: readonly [ReasoningLevel.Low, ReasoningLevel.Medium, ReasoningLevel.High, ReasoningLevel.Max];
4
+ export declare const AUTO_REVIEW_NEEDS_UNATTENDED_MODE: JsonSchema;
5
+ export declare const nanocodeConfigurationJson: (args: {
6
+ title: string;
7
+ reasoning: readonly ReasoningLevel[];
8
+ }) => JsonSchema;
9
+ export declare const NANOCODE_CLAUDE_HARNESS: HarnessDefinitionIface;
10
+ export interface ServerlessNanocodeClaudeInputIface {
11
+ model: string;
12
+ reasoning?: (typeof CLAUDE_REASONING_LEVELS)[number] | `${(typeof CLAUDE_REASONING_LEVELS)[number]}`;
13
+ inference?: InferenceInput;
14
+ permissionMode?: PermissionInput;
15
+ approvalsReviewer?: ApprovalsReviewer | `${ApprovalsReviewer}`;
16
+ environment?: HarnessEnvironmentIface;
17
+ }
18
+ export declare const serverlessNanocodeClaude: ({ environment, ...configuration }: ServerlessNanocodeClaudeInputIface) => HarnessSettingsIface;
@@ -0,0 +1,101 @@
1
+ import { defineHarness } from "@finalai/agent-definition/authoring";
2
+ import {
3
+ CredentialDelivery,
4
+ HarnessFeature,
5
+ HarnessService,
6
+ InferenceSourceKind,
7
+ McpTransportKind,
8
+ PermissionLevel,
9
+ PromptWhileRunning,
10
+ SandboxWire
11
+ } from "@finalai/agent-provider";
12
+ import {
13
+ ApprovalsReviewer,
14
+ approvalsReviewerJson,
15
+ configObjectJson,
16
+ harnessSettings,
17
+ inferenceJson,
18
+ modelJson,
19
+ permissionModeJson,
20
+ reasoningJson,
21
+ ReasoningLevel
22
+ } from "./config-fields.mjs";
23
+ import { ModelVendor } from "./model-reference.mjs";
24
+ import { FinalAcpAdapter, FinalHarness, FinalHarnessInterface, FinalWorkerProgram } from "./names.mjs";
25
+ const CLAUDE_REASONING_LEVELS = [
26
+ ReasoningLevel.Low,
27
+ ReasoningLevel.Medium,
28
+ ReasoningLevel.High,
29
+ ReasoningLevel.Max
30
+ ];
31
+ const AUTO_REVIEW_NEEDS_UNATTENDED_MODE = {
32
+ anyOf: [
33
+ {
34
+ not: {
35
+ required: ["approvalsReviewer"],
36
+ properties: { approvalsReviewer: { const: ApprovalsReviewer.AutoReview } }
37
+ }
38
+ },
39
+ {
40
+ required: ["permissionMode"],
41
+ properties: { permissionMode: { enum: [PermissionLevel.Review, PermissionLevel.Auto] } }
42
+ }
43
+ ]
44
+ };
45
+ const nanocodeConfigurationJson = (args) => ({
46
+ ...configObjectJson({
47
+ required: ["model"],
48
+ title: args.title,
49
+ properties: {
50
+ model: modelJson(),
51
+ reasoning: reasoningJson(args.reasoning),
52
+ inference: inferenceJson(),
53
+ permissionMode: permissionModeJson(),
54
+ approvalsReviewer: approvalsReviewerJson()
55
+ }
56
+ }),
57
+ allOf: [AUTO_REVIEW_NEEDS_UNATTENDED_MODE]
58
+ });
59
+ const NANOCODE_CLAUDE_HARNESS = defineHarness({
60
+ title: "Claude on nanocode",
61
+ description: "nanocode's Claude engine, run per session on a worker runtime.",
62
+ configurationSchema: nanocodeConfigurationJson({
63
+ title: "Claude on nanocode",
64
+ reasoning: CLAUDE_REASONING_LEVELS
65
+ }),
66
+ features: Object.values(HarnessFeature),
67
+ lowestPermission: PermissionLevel.Ask,
68
+ // Subscriptions are the Claude setup token, used as a bearer.
69
+ inference: {
70
+ vendors: [ModelVendor.Anthropic],
71
+ kinds: [
72
+ InferenceSourceKind.Subscription,
73
+ InferenceSourceKind.ApiKey,
74
+ InferenceSourceKind.Final
75
+ ],
76
+ delivery: CredentialDelivery.PerRequest
77
+ },
78
+ interface: FinalHarnessInterface.Nanocode,
79
+ adapter: FinalAcpAdapter.Nanocode,
80
+ run: { worker: { program: FinalWorkerProgram.NanocodeClaude } },
81
+ services: [HarnessService.SessionStore, HarnessService.FrameAttachments],
82
+ mcp: [McpTransportKind.Acp, McpTransportKind.Http],
83
+ consumes: [SandboxWire.HandleRpc],
84
+ supports: { observe: true, resumeReplay: true, authorMeta: true },
85
+ // A prompt that arrives while a turn runs waits for it. Open approvals are
86
+ // asked again with new ids after a lost invocation, so no disconnect survival.
87
+ promptWhileRunning: PromptWhileRunning.Queue,
88
+ sessionSurvivesDisconnect: false
89
+ });
90
+ const serverlessNanocodeClaude = ({
91
+ environment,
92
+ ...configuration
93
+ }) => harnessSettings({ harness: FinalHarness.NanocodeClaude, configuration, environment });
94
+ export {
95
+ AUTO_REVIEW_NEEDS_UNATTENDED_MODE,
96
+ CLAUDE_REASONING_LEVELS,
97
+ NANOCODE_CLAUDE_HARNESS,
98
+ nanocodeConfigurationJson,
99
+ serverlessNanocodeClaude
100
+ };
101
+ //# sourceMappingURL=nanocode-claude.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/harnesses/nanocode-claude.ts"],
4
+ "sourcesContent": ["import { defineHarness } from '@finalai/agent-definition/authoring';\nimport {\n CredentialDelivery,\n HarnessFeature,\n HarnessService,\n InferenceSourceKind,\n McpTransportKind,\n PermissionLevel,\n PromptWhileRunning,\n SandboxWire,\n type HarnessDefinitionIface,\n type HarnessEnvironmentIface,\n type HarnessSettingsIface,\n type JsonSchema,\n} from '@finalai/agent-provider';\nimport {\n ApprovalsReviewer,\n approvalsReviewerJson,\n configObjectJson,\n harnessSettings,\n inferenceJson,\n modelJson,\n permissionModeJson,\n reasoningJson,\n ReasoningLevel,\n type InferenceInput,\n type PermissionInput,\n} from \"./config-fields.mjs\";\nimport { ModelVendor } from \"./model-reference.mjs\";\nimport { FinalAcpAdapter, FinalHarness, FinalHarnessInterface, FinalWorkerProgram } from \"./names.mjs\";\n\n// nanocode's Claude engine as a worker program. It drives the sandboxes\n// provided for `files` and `shell` with its own tools (Read, Write, Bash,\n// BashOutput).\n\nexport const CLAUDE_REASONING_LEVELS = [\n ReasoningLevel.Low,\n ReasoningLevel.Medium,\n ReasoningLevel.High,\n ReasoningLevel.Max,\n] as const;\n\n// A reviewer model answering approvals means no person is asked, so it needs\n// a mode that does not promise one: no auto-review, or review or auto.\nexport const AUTO_REVIEW_NEEDS_UNATTENDED_MODE: JsonSchema = {\n anyOf: [\n {\n not: {\n required: ['approvalsReviewer'],\n properties: { approvalsReviewer: { const: ApprovalsReviewer.AutoReview } },\n },\n },\n {\n required: ['permissionMode'],\n properties: { permissionMode: { enum: [PermissionLevel.Review, PermissionLevel.Auto] } },\n },\n ],\n};\n\nexport const nanocodeConfigurationJson = (args: {\n title: string;\n reasoning: readonly ReasoningLevel[];\n}): JsonSchema => ({\n ...configObjectJson({\n required: ['model'],\n title: args.title,\n properties: {\n model: modelJson(),\n reasoning: reasoningJson(args.reasoning),\n inference: inferenceJson(),\n permissionMode: permissionModeJson(),\n approvalsReviewer: approvalsReviewerJson(),\n },\n }),\n allOf: [AUTO_REVIEW_NEEDS_UNATTENDED_MODE],\n});\n\nexport const NANOCODE_CLAUDE_HARNESS: HarnessDefinitionIface = defineHarness({\n title: 'Claude on nanocode',\n description: \"nanocode's Claude engine, run per session on a worker runtime.\",\n configurationSchema: nanocodeConfigurationJson({\n title: 'Claude on nanocode',\n reasoning: CLAUDE_REASONING_LEVELS,\n }),\n features: Object.values(HarnessFeature),\n lowestPermission: PermissionLevel.Ask,\n // Subscriptions are the Claude setup token, used as a bearer.\n inference: {\n vendors: [ModelVendor.Anthropic],\n kinds: [\n InferenceSourceKind.Subscription,\n InferenceSourceKind.ApiKey,\n InferenceSourceKind.Final,\n ],\n delivery: CredentialDelivery.PerRequest,\n },\n interface: FinalHarnessInterface.Nanocode,\n adapter: FinalAcpAdapter.Nanocode,\n run: { worker: { program: FinalWorkerProgram.NanocodeClaude } },\n services: [HarnessService.SessionStore, HarnessService.FrameAttachments],\n mcp: [McpTransportKind.Acp, McpTransportKind.Http],\n consumes: [SandboxWire.HandleRpc],\n supports: { observe: true, resumeReplay: true, authorMeta: true },\n // A prompt that arrives while a turn runs waits for it. Open approvals are\n // asked again with new ids after a lost invocation, so no disconnect survival.\n promptWhileRunning: PromptWhileRunning.Queue,\n sessionSurvivesDisconnect: false,\n});\n\nexport interface ServerlessNanocodeClaudeInputIface {\n model: string;\n reasoning?:\n | (typeof CLAUDE_REASONING_LEVELS)[number]\n | `${(typeof CLAUDE_REASONING_LEVELS)[number]}`;\n inference?: InferenceInput;\n permissionMode?: PermissionInput;\n approvalsReviewer?: ApprovalsReviewer | `${ApprovalsReviewer}`;\n // The worker-runtime sandbox it runs in; absent: the caller's plan creates one.\n environment?: HarnessEnvironmentIface;\n}\n\nexport const serverlessNanocodeClaude = ({\n environment,\n ...configuration\n}: ServerlessNanocodeClaudeInputIface): HarnessSettingsIface =>\n harnessSettings({ harness: FinalHarness.NanocodeClaude, configuration, environment });\n"],
5
+ "mappings": "AAAA,SAAS,qBAAqB;AAC9B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAKK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB,cAAc,uBAAuB,0BAA0B;AAMlF,MAAM,0BAA0B;AAAA,EACrC,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AACjB;AAIO,MAAM,oCAAgD;AAAA,EAC3D,OAAO;AAAA,IACL;AAAA,MACE,KAAK;AAAA,QACH,UAAU,CAAC,mBAAmB;AAAA,QAC9B,YAAY,EAAE,mBAAmB,EAAE,OAAO,kBAAkB,WAAW,EAAE;AAAA,MAC3E;AAAA,IACF;AAAA,IACA;AAAA,MACE,UAAU,CAAC,gBAAgB;AAAA,MAC3B,YAAY,EAAE,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,QAAQ,gBAAgB,IAAI,EAAE,EAAE;AAAA,IACzF;AAAA,EACF;AACF;AAEO,MAAM,4BAA4B,CAAC,UAGvB;AAAA,EACjB,GAAG,iBAAiB;AAAA,IAClB,UAAU,CAAC,OAAO;AAAA,IAClB,OAAO,KAAK;AAAA,IACZ,YAAY;AAAA,MACV,OAAO,UAAU;AAAA,MACjB,WAAW,cAAc,KAAK,SAAS;AAAA,MACvC,WAAW,cAAc;AAAA,MACzB,gBAAgB,mBAAmB;AAAA,MACnC,mBAAmB,sBAAsB;AAAA,IAC3C;AAAA,EACF,CAAC;AAAA,EACD,OAAO,CAAC,iCAAiC;AAC3C;AAEO,MAAM,0BAAkD,cAAc;AAAA,EAC3E,OAAO;AAAA,EACP,aAAa;AAAA,EACb,qBAAqB,0BAA0B;AAAA,IAC7C,OAAO;AAAA,IACP,WAAW;AAAA,EACb,CAAC;AAAA,EACD,UAAU,OAAO,OAAO,cAAc;AAAA,EACtC,kBAAkB,gBAAgB;AAAA;AAAA,EAElC,WAAW;AAAA,IACT,SAAS,CAAC,YAAY,SAAS;AAAA,IAC/B,OAAO;AAAA,MACL,oBAAoB;AAAA,MACpB,oBAAoB;AAAA,MACpB,oBAAoB;AAAA,IACtB;AAAA,IACA,UAAU,mBAAmB;AAAA,EAC/B;AAAA,EACA,WAAW,sBAAsB;AAAA,EACjC,SAAS,gBAAgB;AAAA,EACzB,KAAK,EAAE,QAAQ,EAAE,SAAS,mBAAmB,eAAe,EAAE;AAAA,EAC9D,UAAU,CAAC,eAAe,cAAc,eAAe,gBAAgB;AAAA,EACvE,KAAK,CAAC,iBAAiB,KAAK,iBAAiB,IAAI;AAAA,EACjD,UAAU,CAAC,YAAY,SAAS;AAAA,EAChC,UAAU,EAAE,SAAS,MAAM,cAAc,MAAM,YAAY,KAAK;AAAA;AAAA;AAAA,EAGhE,oBAAoB,mBAAmB;AAAA,EACvC,2BAA2B;AAC7B,CAAC;AAcM,MAAM,2BAA2B,CAAC;AAAA,EACvC;AAAA,EACA,GAAG;AACL,MACE,gBAAgB,EAAE,SAAS,aAAa,gBAAgB,eAAe,YAAY,CAAC;",
6
+ "names": []
7
+ }
@@ -0,0 +1,13 @@
1
+ import { type HarnessDefinitionIface, type HarnessEnvironmentIface, type HarnessSettingsIface } from '@finalai/agent-provider';
2
+ import { ReasoningLevel, type ApprovalsReviewer, type InferenceInput, type PermissionInput } from "./config-fields.mjs";
3
+ export declare const CODEX_REASONING_LEVELS: readonly [ReasoningLevel.Low, ReasoningLevel.Medium, ReasoningLevel.High, ReasoningLevel.Max];
4
+ export declare const NANOCODE_CODEX_HARNESS: HarnessDefinitionIface;
5
+ export interface ServerlessNanocodeCodexInputIface {
6
+ model: string;
7
+ reasoning?: (typeof CODEX_REASONING_LEVELS)[number] | `${(typeof CODEX_REASONING_LEVELS)[number]}`;
8
+ inference?: InferenceInput;
9
+ permissionMode?: PermissionInput;
10
+ approvalsReviewer?: ApprovalsReviewer | `${ApprovalsReviewer}`;
11
+ environment?: HarnessEnvironmentIface;
12
+ }
13
+ export declare const serverlessNanocodeCodex: ({ environment, ...configuration }: ServerlessNanocodeCodexInputIface) => HarnessSettingsIface;
@@ -0,0 +1,64 @@
1
+ import { defineHarness } from "@finalai/agent-definition/authoring";
2
+ import {
3
+ CredentialDelivery,
4
+ HarnessFeature,
5
+ HarnessService,
6
+ InferenceSourceKind,
7
+ McpTransportKind,
8
+ PermissionLevel,
9
+ PromptWhileRunning,
10
+ SandboxWire
11
+ } from "@finalai/agent-provider";
12
+ import {
13
+ ReasoningLevel,
14
+ harnessSettings
15
+ } from "./config-fields.mjs";
16
+ import { ModelVendor } from "./model-reference.mjs";
17
+ import { FinalAcpAdapter, FinalHarness, FinalHarnessInterface, FinalWorkerProgram } from "./names.mjs";
18
+ import { nanocodeConfigurationJson } from "./nanocode-claude.mjs";
19
+ const CODEX_REASONING_LEVELS = [
20
+ ReasoningLevel.Low,
21
+ ReasoningLevel.Medium,
22
+ ReasoningLevel.High,
23
+ ReasoningLevel.Max
24
+ ];
25
+ const NANOCODE_CODEX_HARNESS = defineHarness({
26
+ title: "Codex on nanocode",
27
+ description: "nanocode's Codex engine, run per session on a worker runtime.",
28
+ configurationSchema: nanocodeConfigurationJson({
29
+ title: "Codex on nanocode",
30
+ reasoning: CODEX_REASONING_LEVELS
31
+ }),
32
+ features: Object.values(HarnessFeature),
33
+ lowestPermission: PermissionLevel.Ask,
34
+ inference: {
35
+ vendors: [ModelVendor.OpenAI],
36
+ kinds: [
37
+ InferenceSourceKind.Subscription,
38
+ InferenceSourceKind.ApiKey,
39
+ InferenceSourceKind.Final
40
+ ],
41
+ delivery: CredentialDelivery.PerRequest
42
+ },
43
+ interface: FinalHarnessInterface.Nanocode,
44
+ adapter: FinalAcpAdapter.Nanocode,
45
+ run: { worker: { program: FinalWorkerProgram.NanocodeCodex } },
46
+ services: [HarnessService.FrameAttachments, HarnessService.SubscriptionRelay],
47
+ mcp: [McpTransportKind.Acp, McpTransportKind.Http],
48
+ consumes: [SandboxWire.HandleRpc],
49
+ supports: { observe: true, resumeReplay: true, authorMeta: true },
50
+ // A prompt that arrives while a turn runs steers into it; open approvals are
51
+ // asked again with new ids after a lost invocation, so no disconnect survival.
52
+ promptWhileRunning: PromptWhileRunning.Inject,
53
+ sessionSurvivesDisconnect: false
54
+ });
55
+ const serverlessNanocodeCodex = ({
56
+ environment,
57
+ ...configuration
58
+ }) => harnessSettings({ harness: FinalHarness.NanocodeCodex, configuration, environment });
59
+ export {
60
+ CODEX_REASONING_LEVELS,
61
+ NANOCODE_CODEX_HARNESS,
62
+ serverlessNanocodeCodex
63
+ };
64
+ //# sourceMappingURL=nanocode-codex.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/harnesses/nanocode-codex.ts"],
4
+ "sourcesContent": ["import { defineHarness } from '@finalai/agent-definition/authoring';\nimport {\n CredentialDelivery,\n HarnessFeature,\n HarnessService,\n InferenceSourceKind,\n McpTransportKind,\n PermissionLevel,\n PromptWhileRunning,\n SandboxWire,\n type HarnessDefinitionIface,\n type HarnessEnvironmentIface,\n type HarnessSettingsIface,\n} from '@finalai/agent-provider';\nimport {\n ReasoningLevel,\n harnessSettings,\n type ApprovalsReviewer,\n type InferenceInput,\n type PermissionInput,\n} from \"./config-fields.mjs\";\nimport { ModelVendor } from \"./model-reference.mjs\";\nimport { FinalAcpAdapter, FinalHarness, FinalHarnessInterface, FinalWorkerProgram } from \"./names.mjs\";\nimport { nanocodeConfigurationJson } from \"./nanocode-claude.mjs\";\n\n// nanocode's Codex engine as a worker program, Responses Lite models only. It\n// drives the sandboxes provided for `files` and `shell` with its own tools\n// (apply_patch, view_image, exec_command, write_stdin).\n\n// The final://schemas/reasoning fragment has no xhigh/ultra yet; nanocode's\n// policies accept the rest.\nexport const CODEX_REASONING_LEVELS = [\n ReasoningLevel.Low,\n ReasoningLevel.Medium,\n ReasoningLevel.High,\n ReasoningLevel.Max,\n] as const;\n\nexport const NANOCODE_CODEX_HARNESS: HarnessDefinitionIface = defineHarness({\n title: 'Codex on nanocode',\n description: \"nanocode's Codex engine, run per session on a worker runtime.\",\n configurationSchema: nanocodeConfigurationJson({\n title: 'Codex on nanocode',\n reasoning: CODEX_REASONING_LEVELS,\n }),\n features: Object.values(HarnessFeature),\n lowestPermission: PermissionLevel.Ask,\n inference: {\n vendors: [ModelVendor.OpenAI],\n kinds: [\n InferenceSourceKind.Subscription,\n InferenceSourceKind.ApiKey,\n InferenceSourceKind.Final,\n ],\n delivery: CredentialDelivery.PerRequest,\n },\n interface: FinalHarnessInterface.Nanocode,\n adapter: FinalAcpAdapter.Nanocode,\n run: { worker: { program: FinalWorkerProgram.NanocodeCodex } },\n services: [HarnessService.FrameAttachments, HarnessService.SubscriptionRelay],\n mcp: [McpTransportKind.Acp, McpTransportKind.Http],\n consumes: [SandboxWire.HandleRpc],\n supports: { observe: true, resumeReplay: true, authorMeta: true },\n // A prompt that arrives while a turn runs steers into it; open approvals are\n // asked again with new ids after a lost invocation, so no disconnect survival.\n promptWhileRunning: PromptWhileRunning.Inject,\n sessionSurvivesDisconnect: false,\n});\n\nexport interface ServerlessNanocodeCodexInputIface {\n model: string;\n reasoning?:\n | (typeof CODEX_REASONING_LEVELS)[number]\n | `${(typeof CODEX_REASONING_LEVELS)[number]}`;\n inference?: InferenceInput;\n permissionMode?: PermissionInput;\n approvalsReviewer?: ApprovalsReviewer | `${ApprovalsReviewer}`;\n // The worker-runtime sandbox it runs in; absent: the caller's plan creates one.\n environment?: HarnessEnvironmentIface;\n}\n\nexport const serverlessNanocodeCodex = ({\n environment,\n ...configuration\n}: ServerlessNanocodeCodexInputIface): HarnessSettingsIface =>\n harnessSettings({ harness: FinalHarness.NanocodeCodex, configuration, environment });\n"],
5
+ "mappings": "AAAA,SAAS,qBAAqB;AAC9B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAIK;AACP,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB,cAAc,uBAAuB,0BAA0B;AACzF,SAAS,iCAAiC;AAQnC,MAAM,yBAAyB;AAAA,EACpC,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AACjB;AAEO,MAAM,yBAAiD,cAAc;AAAA,EAC1E,OAAO;AAAA,EACP,aAAa;AAAA,EACb,qBAAqB,0BAA0B;AAAA,IAC7C,OAAO;AAAA,IACP,WAAW;AAAA,EACb,CAAC;AAAA,EACD,UAAU,OAAO,OAAO,cAAc;AAAA,EACtC,kBAAkB,gBAAgB;AAAA,EAClC,WAAW;AAAA,IACT,SAAS,CAAC,YAAY,MAAM;AAAA,IAC5B,OAAO;AAAA,MACL,oBAAoB;AAAA,MACpB,oBAAoB;AAAA,MACpB,oBAAoB;AAAA,IACtB;AAAA,IACA,UAAU,mBAAmB;AAAA,EAC/B;AAAA,EACA,WAAW,sBAAsB;AAAA,EACjC,SAAS,gBAAgB;AAAA,EACzB,KAAK,EAAE,QAAQ,EAAE,SAAS,mBAAmB,cAAc,EAAE;AAAA,EAC7D,UAAU,CAAC,eAAe,kBAAkB,eAAe,iBAAiB;AAAA,EAC5E,KAAK,CAAC,iBAAiB,KAAK,iBAAiB,IAAI;AAAA,EACjD,UAAU,CAAC,YAAY,SAAS;AAAA,EAChC,UAAU,EAAE,SAAS,MAAM,cAAc,MAAM,YAAY,KAAK;AAAA;AAAA;AAAA,EAGhE,oBAAoB,mBAAmB;AAAA,EACvC,2BAA2B;AAC7B,CAAC;AAcM,MAAM,0BAA0B,CAAC;AAAA,EACtC;AAAA,EACA,GAAG;AACL,MACE,gBAAgB,EAAE,SAAS,aAAa,eAAe,eAAe,YAAY,CAAC;",
6
+ "names": []
7
+ }
@@ -0,0 +1,12 @@
1
+ import { type HarnessDefinitionIface, type HarnessEnvironmentIface, type HarnessSettingsIface } from '@finalai/agent-provider';
2
+ import { ReasoningLevel, type InferenceInput, type PermissionInput } from "./config-fields.mjs";
3
+ export declare const PI_REASONING_LEVELS: readonly [ReasoningLevel.None, ReasoningLevel.Minimal, ReasoningLevel.Low, ReasoningLevel.Medium, ReasoningLevel.High];
4
+ export declare const PI_HARNESS: HarnessDefinitionIface;
5
+ export interface ServerlessPiInputIface {
6
+ model: string;
7
+ reasoning?: (typeof PI_REASONING_LEVELS)[number] | `${(typeof PI_REASONING_LEVELS)[number]}`;
8
+ inference?: InferenceInput;
9
+ permissionMode?: PermissionInput;
10
+ environment?: HarnessEnvironmentIface;
11
+ }
12
+ export declare const serverlessPi: ({ environment, ...configuration }: ServerlessPiInputIface) => HarnessSettingsIface;
@@ -0,0 +1,71 @@
1
+ import { defineHarness } from "@finalai/agent-definition/authoring";
2
+ import {
3
+ CredentialDelivery,
4
+ HarnessFeature,
5
+ HarnessService,
6
+ InferenceSourceKind,
7
+ McpTransportKind,
8
+ PermissionLevel,
9
+ PromptWhileRunning,
10
+ SandboxWire
11
+ } from "@finalai/agent-provider";
12
+ import {
13
+ configObjectJson,
14
+ harnessSettings,
15
+ inferenceJson,
16
+ modelJson,
17
+ permissionModeJson,
18
+ reasoningJson,
19
+ ReasoningLevel
20
+ } from "./config-fields.mjs";
21
+ import { ModelVendor } from "./model-reference.mjs";
22
+ import { FinalAcpAdapter, FinalHarness, FinalHarnessInterface, FinalWorkerProgram } from "./names.mjs";
23
+ const PI_REASONING_LEVELS = [
24
+ ReasoningLevel.None,
25
+ ReasoningLevel.Minimal,
26
+ ReasoningLevel.Low,
27
+ ReasoningLevel.Medium,
28
+ ReasoningLevel.High
29
+ ];
30
+ const PI_HARNESS = defineHarness({
31
+ title: "Pi",
32
+ description: "The Pi coding agent, run per session on a worker runtime.",
33
+ configurationSchema: configObjectJson({
34
+ required: ["model"],
35
+ title: "Pi",
36
+ properties: {
37
+ model: modelJson(),
38
+ reasoning: reasoningJson(PI_REASONING_LEVELS),
39
+ inference: inferenceJson(),
40
+ permissionMode: permissionModeJson()
41
+ }
42
+ }),
43
+ features: Object.values(HarnessFeature),
44
+ lowestPermission: PermissionLevel.Ask,
45
+ inference: {
46
+ vendors: [ModelVendor.OpenRouter, ModelVendor.OpenAI, ModelVendor.Anthropic],
47
+ kinds: [InferenceSourceKind.ApiKey, InferenceSourceKind.Final],
48
+ delivery: CredentialDelivery.PerRequest
49
+ },
50
+ interface: FinalHarnessInterface.PiAgent,
51
+ adapter: FinalAcpAdapter.Pi,
52
+ run: { worker: { program: FinalWorkerProgram.Pi } },
53
+ services: [HarnessService.FrameAttachments],
54
+ mcp: [McpTransportKind.Acp, McpTransportKind.Http],
55
+ consumes: [SandboxWire.HandleRpc],
56
+ supports: { observe: true, resumeReplay: true, authorMeta: true },
57
+ // A steer joins the running turn. Across a lost invocation an open ask is
58
+ // not raised again with its id, so the session does not survive a disconnect.
59
+ promptWhileRunning: PromptWhileRunning.Inject,
60
+ sessionSurvivesDisconnect: false
61
+ });
62
+ const serverlessPi = ({
63
+ environment,
64
+ ...configuration
65
+ }) => harnessSettings({ harness: FinalHarness.Pi, configuration, environment });
66
+ export {
67
+ PI_HARNESS,
68
+ PI_REASONING_LEVELS,
69
+ serverlessPi
70
+ };
71
+ //# sourceMappingURL=pi.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/harnesses/pi.ts"],
4
+ "sourcesContent": ["import { defineHarness } from '@finalai/agent-definition/authoring';\nimport {\n CredentialDelivery,\n HarnessFeature,\n HarnessService,\n InferenceSourceKind,\n McpTransportKind,\n PermissionLevel,\n PromptWhileRunning,\n SandboxWire,\n type HarnessDefinitionIface,\n type HarnessEnvironmentIface,\n type HarnessSettingsIface,\n} from '@finalai/agent-provider';\nimport {\n configObjectJson,\n harnessSettings,\n inferenceJson,\n modelJson,\n permissionModeJson,\n reasoningJson,\n ReasoningLevel,\n type InferenceInput,\n type PermissionInput,\n} from \"./config-fields.mjs\";\nimport { ModelVendor } from \"./model-reference.mjs\";\nimport { FinalAcpAdapter, FinalHarness, FinalHarnessInterface, FinalWorkerProgram } from \"./names.mjs\";\n\n// Pi (pi-mono) as a worker program, one durable instance per harness session.\n// It drives the sandboxes provided for `files` and `shell` with its own tools\n// (read, write, edit, grep, find, ls, bash). There is no public process\n// adapter for Pi's interface yet, so Pi runs only as a worker or at a URL.\n\nexport const PI_REASONING_LEVELS = [\n ReasoningLevel.None,\n ReasoningLevel.Minimal,\n ReasoningLevel.Low,\n ReasoningLevel.Medium,\n ReasoningLevel.High,\n] as const;\n\nexport const PI_HARNESS: HarnessDefinitionIface = defineHarness({\n title: 'Pi',\n description: 'The Pi coding agent, run per session on a worker runtime.',\n configurationSchema: configObjectJson({\n required: ['model'],\n title: 'Pi',\n properties: {\n model: modelJson(),\n reasoning: reasoningJson(PI_REASONING_LEVELS),\n inference: inferenceJson(),\n permissionMode: permissionModeJson(),\n },\n }),\n features: Object.values(HarnessFeature),\n lowestPermission: PermissionLevel.Ask,\n inference: {\n vendors: [ModelVendor.OpenRouter, ModelVendor.OpenAI, ModelVendor.Anthropic],\n kinds: [InferenceSourceKind.ApiKey, InferenceSourceKind.Final],\n delivery: CredentialDelivery.PerRequest,\n },\n interface: FinalHarnessInterface.PiAgent,\n adapter: FinalAcpAdapter.Pi,\n run: { worker: { program: FinalWorkerProgram.Pi } },\n services: [HarnessService.FrameAttachments],\n mcp: [McpTransportKind.Acp, McpTransportKind.Http],\n consumes: [SandboxWire.HandleRpc],\n supports: { observe: true, resumeReplay: true, authorMeta: true },\n // A steer joins the running turn. Across a lost invocation an open ask is\n // not raised again with its id, so the session does not survive a disconnect.\n promptWhileRunning: PromptWhileRunning.Inject,\n sessionSurvivesDisconnect: false,\n});\n\nexport interface ServerlessPiInputIface {\n model: string;\n reasoning?: (typeof PI_REASONING_LEVELS)[number] | `${(typeof PI_REASONING_LEVELS)[number]}`;\n inference?: InferenceInput;\n permissionMode?: PermissionInput;\n // The worker-runtime sandbox it runs in, or an endpoint already running it;\n // absent: the client creates one the session or conversation owns.\n environment?: HarnessEnvironmentIface;\n}\n\nexport const serverlessPi = ({\n environment,\n ...configuration\n}: ServerlessPiInputIface): HarnessSettingsIface =>\n harnessSettings({ harness: FinalHarness.Pi, configuration, environment });\n"],
5
+ "mappings": "AAAA,SAAS,qBAAqB;AAC9B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB,cAAc,uBAAuB,0BAA0B;AAOlF,MAAM,sBAAsB;AAAA,EACjC,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AACjB;AAEO,MAAM,aAAqC,cAAc;AAAA,EAC9D,OAAO;AAAA,EACP,aAAa;AAAA,EACb,qBAAqB,iBAAiB;AAAA,IACpC,UAAU,CAAC,OAAO;AAAA,IAClB,OAAO;AAAA,IACP,YAAY;AAAA,MACV,OAAO,UAAU;AAAA,MACjB,WAAW,cAAc,mBAAmB;AAAA,MAC5C,WAAW,cAAc;AAAA,MACzB,gBAAgB,mBAAmB;AAAA,IACrC;AAAA,EACF,CAAC;AAAA,EACD,UAAU,OAAO,OAAO,cAAc;AAAA,EACtC,kBAAkB,gBAAgB;AAAA,EAClC,WAAW;AAAA,IACT,SAAS,CAAC,YAAY,YAAY,YAAY,QAAQ,YAAY,SAAS;AAAA,IAC3E,OAAO,CAAC,oBAAoB,QAAQ,oBAAoB,KAAK;AAAA,IAC7D,UAAU,mBAAmB;AAAA,EAC/B;AAAA,EACA,WAAW,sBAAsB;AAAA,EACjC,SAAS,gBAAgB;AAAA,EACzB,KAAK,EAAE,QAAQ,EAAE,SAAS,mBAAmB,GAAG,EAAE;AAAA,EAClD,UAAU,CAAC,eAAe,gBAAgB;AAAA,EAC1C,KAAK,CAAC,iBAAiB,KAAK,iBAAiB,IAAI;AAAA,EACjD,UAAU,CAAC,YAAY,SAAS;AAAA,EAChC,UAAU,EAAE,SAAS,MAAM,cAAc,MAAM,YAAY,KAAK;AAAA;AAAA;AAAA,EAGhE,oBAAoB,mBAAmB;AAAA,EACvC,2BAA2B;AAC7B,CAAC;AAYM,MAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA,GAAG;AACL,MACE,gBAAgB,EAAE,SAAS,aAAa,IAAI,eAAe,YAAY,CAAC;",
6
+ "names": []
7
+ }
@@ -0,0 +1,9 @@
1
+ import { type CreateIntegrationRequestIface } from '@finalai/agent-protocol/agent-platform/integrations';
2
+ export declare const FINAL_GATEWAY_URL = "final://mcp";
3
+ export declare const FINAL_GATEWAY_SCOPES: Record<string, string[]>;
4
+ export interface FinalGatewayInputIface {
5
+ url: string;
6
+ name?: string;
7
+ scopes?: Record<string, string[]>;
8
+ }
9
+ export declare const finalGateway: (input: FinalGatewayInputIface) => CreateIntegrationRequestIface;
@@ -0,0 +1,29 @@
1
+ import {
2
+ createIntegrationRequestSchema,
3
+ IntegrationAuthKind
4
+ } from "@finalai/agent-protocol/agent-platform/integrations";
5
+ const FINAL_GATEWAY_URL = "final://mcp";
6
+ const FINAL_GATEWAY_SCOPES = {
7
+ api: [
8
+ "session:requirements",
9
+ "agents:read",
10
+ "agents:execute",
11
+ "conversations:read",
12
+ "conversations:write"
13
+ ],
14
+ reach: ["session"]
15
+ };
16
+ const finalGateway = (input) => createIntegrationRequestSchema.parse({
17
+ name: input.name ?? "final",
18
+ mcp: { url: input.url },
19
+ auth: {
20
+ kind: IntegrationAuthKind.PlatformIdentity,
21
+ scopes: input.scopes ?? FINAL_GATEWAY_SCOPES
22
+ }
23
+ });
24
+ export {
25
+ FINAL_GATEWAY_SCOPES,
26
+ FINAL_GATEWAY_URL,
27
+ finalGateway
28
+ };
29
+ //# sourceMappingURL=integrations.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/integrations.ts"],
4
+ "sourcesContent": ["import {\n createIntegrationRequestSchema,\n IntegrationAuthKind,\n type CreateIntegrationRequestIface,\n} from '@finalai/agent-protocol/agent-platform/integrations';\n\n// Final's MCP gateway as an ordinary integration:\n// `project.integrations.create(finalGateway({ url }))` returns the id a caller\n// provides for an agent's slot. It authenticates with the platform's identity\n// assertion for the calling session, which any server can verify; nothing\n// about it is first-party only, and the platform resolves no special URL.\n\n// Deprecated: the platform resolves no placeholder; pass the gateway's URL.\nexport const FINAL_GATEWAY_URL = 'final://mcp';\n\n// What the gateway's assertion lets it do as the calling session on the\n// platform API (`api`): read the session's requirements and ask for an\n// optional one, read and run agents, and read and write conversations. `reach`\n// confines it to the session's own conversation and its linked children.\nexport const FINAL_GATEWAY_SCOPES: Record<string, string[]> = {\n api: [\n 'session:requirements',\n 'agents:read',\n 'agents:execute',\n 'conversations:read',\n 'conversations:write',\n ],\n reach: ['session'],\n};\n\nexport interface FinalGatewayInputIface {\n // The gateway's MCP endpoint (https).\n url: string;\n // The integration's name in the project; `final` by default.\n name?: string;\n scopes?: Record<string, string[]>;\n}\n\nexport const finalGateway = (input: FinalGatewayInputIface): CreateIntegrationRequestIface =>\n createIntegrationRequestSchema.parse({\n name: input.name ?? 'final',\n mcp: { url: input.url },\n auth: {\n kind: IntegrationAuthKind.PlatformIdentity,\n scopes: input.scopes ?? FINAL_GATEWAY_SCOPES,\n },\n });\n"],
5
+ "mappings": "AAAA;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AASA,MAAM,oBAAoB;AAM1B,MAAM,uBAAiD;AAAA,EAC5D,KAAK;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,OAAO,CAAC,SAAS;AACnB;AAUO,MAAM,eAAe,CAAC,UAC3B,+BAA+B,MAAM;AAAA,EACnC,MAAM,MAAM,QAAQ;AAAA,EACpB,KAAK,EAAE,KAAK,MAAM,IAAI;AAAA,EACtB,MAAM;AAAA,IACJ,MAAM,oBAAoB;AAAA,IAC1B,QAAQ,MAAM,UAAU;AAAA,EAC1B;AACF,CAAC;",
6
+ "names": []
7
+ }
@@ -0,0 +1 @@
1
+ export declare const GENERAL_HARNESS_PROVIDER_SOURCE = "var RUNTIME_KINDS=[\"process\",\"worker\"];var ACP_V2_INTERFACE=\"acp-v2\";var PLACEHOLDER=/\\{\\{\\s*([A-Za-z0-9_.-]+)\\s*\\}\\}/gu,HARNESS_COMMAND_PATH=\"harness.command\",runtimesOf=run=>RUNTIME_KINDS.filter(kind=>run[kind]!=null),isRecord=value=>value!=null&&typeof value==\"object\"&&!Array.isArray(value),isJsonValue=value=>value===null||typeof value==\"string\"||typeof value==\"boolean\"?!0:typeof value==\"number\"?Number.isFinite(value):Array.isArray(value)?value.every(isJsonValue):isRecord(value)&&Object.values(value).every(isJsonValue),isJsonObject=value=>isRecord(value)&&isJsonValue(value),valueAt=(context,path)=>{if(path===HARNESS_COMMAND_PATH)return context.harness?.command;let value=context.configuration;for(let key of path.split(\".\").slice(1)){if(!isRecord(value))return;value=value[key]}return value},isSet=value=>value!=null&&value!==!1,textOf=value=>typeof value==\"string\"?value:JSON.stringify(value),render=(template,context,problems)=>template.replace(PLACEHOLDER,(_match,path)=>{let value=valueAt(context,path);return value==null?(problems.push(`{{${path}}} has no value`),\"\"):textOf(value)}),renderProcess=(run,context,problems)=>{let args=[];for(let arg of run.args)if(typeof arg==\"string\")args.push(render(arg,context,problems));else if(\"spread\"in arg)args.push(...context.harness?.args??[]);else if(isSet(valueAt(context,arg.when)))for(let template of arg.args)args.push(render(template,context,problems));let env={};for(let[key,value]of Object.entries(run.env))typeof value==\"string\"?env[key]=render(value,context,problems):isSet(valueAt(context,value.when))&&(env[key]=render(value.value,context,problems));return{command:render(run.command,context,problems),args,env}},harnessStartFor=args=>{let problems=[],{harness,adapter,configuration}=args;if(!isJsonObject(configuration))return{ok:!1,problems:[\"The configuration is not a JSON object\"]};if(args.runtime===\"process\"){let own2=harness.run.process,wrapper2=adapter==null?null:adapter.run.process;if(own2==null||adapter!=null&&wrapper2==null)return{ok:!1,problems:[\"No process entry to start\"]};let started=renderProcess(own2,{configuration,harness:null},problems),outer=wrapper2==null?started:renderProcess(wrapper2,{configuration,harness:{command:started.command,args:started.args}},problems),env=wrapper2==null?started.env:{...started.env,...outer.env};return problems.length>0?{ok:!1,problems}:{ok:!0,start:{runtime:\"process\",command:outer.command,args:outer.args,env}}}let own=harness.run.worker,wrapper=adapter==null?null:adapter.run.worker;return own==null||adapter!=null&&wrapper==null?{ok:!1,problems:[\"No worker entry to start\"]}:{ok:!0,start:{runtime:\"worker\",program:wrapper?.program??own.program,env:{},input:wrapper==null?{configuration}:{harness:{program:own.program},configuration}}}};var REQUIRED_FINAL_EXTENSIONS=[\"observe\",\"authorMeta\",\"resumeReplay\",\"afterSeqReplay\"],refused=problems=>({unsuitable:problems}),listOf=items=>items.length===0?\"nothing\":items.join(\", \"),urlEndpoint=async args=>{if(args.adapter!=null)return refused([`An ACP endpoint at a URL already speaks ACP and takes no adapter (${args.adapter})`]);let protocol;try{protocol=new URL(args.url).protocol}catch{return refused([`${args.url} is not a URL`])}let transport=protocol===\"wss:\"||protocol===\"ws:\"?\"ws\":protocol===\"https:\"||protocol===\"http:\"?\"http\":null;if(transport==null)return refused([`${args.url}: an ACP endpoint answers over ws(s) or http(s)`]);let headers={};if(args.hop!=null){let token=await args.ctx.secrets.get(args.hop);if(token==null||token.length===0)return refused([`The project has no secret ${args.hop} for ${args.url}`]);headers.authorization=`Bearer ${token}`}return{ref:args.ref,transport,url:args.url,headers,extensions:[...REQUIRED_FINAL_EXTENSIONS]}},sandboxEndpoint=(args,ref,sandboxId)=>{let harness=args.harness,adapter=args.adapter,name=harness.name;if(harness.definition.provider!=null)return refused([`${name} is reached by its own harness provider`]);let problems=[];if(adapter==null&&harness.definition.interface!==ACP_V2_INTERFACE&&problems.push(`${name} speaks ${harness.definition.interface}, not ACP v2, and has no adapter`),adapter!=null){adapter.definition.adapts.includes(harness.definition.interface)||problems.push(`ACP adapter ${adapter.name} adapts ${listOf(adapter.definition.adapts)}, not ${harness.definition.interface}`);let missing=REQUIRED_FINAL_EXTENSIONS.filter(extension=>!adapter.definition.extensions.includes(extension));missing.length>0&&problems.push(`ACP adapter ${adapter.name} does not implement Final's ACP extensions ${listOf(missing)}`)}let runtime=args.runtime,harnessRuntimes=runtimesOf(harness.definition.run),adapterRuntimes=adapter==null?null:runtimesOf(adapter.definition.run);if(runtime==null?problems.push(`Sandbox ${sandboxId} runs nothing ${name} has an entry for`):(harnessRuntimes.includes(runtime)||problems.push(`${name} has no ${runtime} entry (it runs as ${listOf(harnessRuntimes)})`),adapter!=null&&adapterRuntimes!=null&&!adapterRuntimes.includes(runtime)&&problems.push(`ACP adapter ${adapter.name} has no ${runtime} entry (it runs as ${listOf(adapterRuntimes)})`)),problems.length>0||runtime==null)return refused(problems);let started=harnessStartFor({harness:harness.definition,adapter:adapter?.definition??null,runtime,configuration:args.settings.configuration});return started.ok?{ref,transport:\"sandbox\",sandboxId,start:started.start,extensions:[...REQUIRED_FINAL_EXTENSIONS]}:refused(started.problems)},endpointFor=(args,ref,ctx)=>{let environment=args.environment;return environment.kind===\"url\"?urlEndpoint({ref,url:environment.url,hop:environment.hop,adapter:args.adapter?.name??null,ctx}):Promise.resolve(sandboxEndpoint(args,ref,environment.sandboxId))},open=(args,ctx)=>endpointFor(args,{harness:args.harness.name,harnessSessionRef:args.harnessSessionId,generation:0},ctx),resume=(args,ctx)=>endpointFor(args,args.ref,ctx),park=async(_args,_ctx)=>{},close=async(_args,_ctx)=>{},health=async(_args,_ctx)=>({ok:!0,detail:\"The session service watches the program it started\"});export{REQUIRED_FINAL_EXTENSIONS,close,health,open,park,resume};\n";
@@ -0,0 +1,5 @@
1
+ const GENERAL_HARNESS_PROVIDER_SOURCE = 'var RUNTIME_KINDS=["process","worker"];var ACP_V2_INTERFACE="acp-v2";var PLACEHOLDER=/\\{\\{\\s*([A-Za-z0-9_.-]+)\\s*\\}\\}/gu,HARNESS_COMMAND_PATH="harness.command",runtimesOf=run=>RUNTIME_KINDS.filter(kind=>run[kind]!=null),isRecord=value=>value!=null&&typeof value=="object"&&!Array.isArray(value),isJsonValue=value=>value===null||typeof value=="string"||typeof value=="boolean"?!0:typeof value=="number"?Number.isFinite(value):Array.isArray(value)?value.every(isJsonValue):isRecord(value)&&Object.values(value).every(isJsonValue),isJsonObject=value=>isRecord(value)&&isJsonValue(value),valueAt=(context,path)=>{if(path===HARNESS_COMMAND_PATH)return context.harness?.command;let value=context.configuration;for(let key of path.split(".").slice(1)){if(!isRecord(value))return;value=value[key]}return value},isSet=value=>value!=null&&value!==!1,textOf=value=>typeof value=="string"?value:JSON.stringify(value),render=(template,context,problems)=>template.replace(PLACEHOLDER,(_match,path)=>{let value=valueAt(context,path);return value==null?(problems.push(`{{${path}}} has no value`),""):textOf(value)}),renderProcess=(run,context,problems)=>{let args=[];for(let arg of run.args)if(typeof arg=="string")args.push(render(arg,context,problems));else if("spread"in arg)args.push(...context.harness?.args??[]);else if(isSet(valueAt(context,arg.when)))for(let template of arg.args)args.push(render(template,context,problems));let env={};for(let[key,value]of Object.entries(run.env))typeof value=="string"?env[key]=render(value,context,problems):isSet(valueAt(context,value.when))&&(env[key]=render(value.value,context,problems));return{command:render(run.command,context,problems),args,env}},harnessStartFor=args=>{let problems=[],{harness,adapter,configuration}=args;if(!isJsonObject(configuration))return{ok:!1,problems:["The configuration is not a JSON object"]};if(args.runtime==="process"){let own2=harness.run.process,wrapper2=adapter==null?null:adapter.run.process;if(own2==null||adapter!=null&&wrapper2==null)return{ok:!1,problems:["No process entry to start"]};let started=renderProcess(own2,{configuration,harness:null},problems),outer=wrapper2==null?started:renderProcess(wrapper2,{configuration,harness:{command:started.command,args:started.args}},problems),env=wrapper2==null?started.env:{...started.env,...outer.env};return problems.length>0?{ok:!1,problems}:{ok:!0,start:{runtime:"process",command:outer.command,args:outer.args,env}}}let own=harness.run.worker,wrapper=adapter==null?null:adapter.run.worker;return own==null||adapter!=null&&wrapper==null?{ok:!1,problems:["No worker entry to start"]}:{ok:!0,start:{runtime:"worker",program:wrapper?.program??own.program,env:{},input:wrapper==null?{configuration}:{harness:{program:own.program},configuration}}}};var REQUIRED_FINAL_EXTENSIONS=["observe","authorMeta","resumeReplay","afterSeqReplay"],refused=problems=>({unsuitable:problems}),listOf=items=>items.length===0?"nothing":items.join(", "),urlEndpoint=async args=>{if(args.adapter!=null)return refused([`An ACP endpoint at a URL already speaks ACP and takes no adapter (${args.adapter})`]);let protocol;try{protocol=new URL(args.url).protocol}catch{return refused([`${args.url} is not a URL`])}let transport=protocol==="wss:"||protocol==="ws:"?"ws":protocol==="https:"||protocol==="http:"?"http":null;if(transport==null)return refused([`${args.url}: an ACP endpoint answers over ws(s) or http(s)`]);let headers={};if(args.hop!=null){let token=await args.ctx.secrets.get(args.hop);if(token==null||token.length===0)return refused([`The project has no secret ${args.hop} for ${args.url}`]);headers.authorization=`Bearer ${token}`}return{ref:args.ref,transport,url:args.url,headers,extensions:[...REQUIRED_FINAL_EXTENSIONS]}},sandboxEndpoint=(args,ref,sandboxId)=>{let harness=args.harness,adapter=args.adapter,name=harness.name;if(harness.definition.provider!=null)return refused([`${name} is reached by its own harness provider`]);let problems=[];if(adapter==null&&harness.definition.interface!==ACP_V2_INTERFACE&&problems.push(`${name} speaks ${harness.definition.interface}, not ACP v2, and has no adapter`),adapter!=null){adapter.definition.adapts.includes(harness.definition.interface)||problems.push(`ACP adapter ${adapter.name} adapts ${listOf(adapter.definition.adapts)}, not ${harness.definition.interface}`);let missing=REQUIRED_FINAL_EXTENSIONS.filter(extension=>!adapter.definition.extensions.includes(extension));missing.length>0&&problems.push(`ACP adapter ${adapter.name} does not implement Final\'s ACP extensions ${listOf(missing)}`)}let runtime=args.runtime,harnessRuntimes=runtimesOf(harness.definition.run),adapterRuntimes=adapter==null?null:runtimesOf(adapter.definition.run);if(runtime==null?problems.push(`Sandbox ${sandboxId} runs nothing ${name} has an entry for`):(harnessRuntimes.includes(runtime)||problems.push(`${name} has no ${runtime} entry (it runs as ${listOf(harnessRuntimes)})`),adapter!=null&&adapterRuntimes!=null&&!adapterRuntimes.includes(runtime)&&problems.push(`ACP adapter ${adapter.name} has no ${runtime} entry (it runs as ${listOf(adapterRuntimes)})`)),problems.length>0||runtime==null)return refused(problems);let started=harnessStartFor({harness:harness.definition,adapter:adapter?.definition??null,runtime,configuration:args.settings.configuration});return started.ok?{ref,transport:"sandbox",sandboxId,start:started.start,extensions:[...REQUIRED_FINAL_EXTENSIONS]}:refused(started.problems)},endpointFor=(args,ref,ctx)=>{let environment=args.environment;return environment.kind==="url"?urlEndpoint({ref,url:environment.url,hop:environment.hop,adapter:args.adapter?.name??null,ctx}):Promise.resolve(sandboxEndpoint(args,ref,environment.sandboxId))},open=(args,ctx)=>endpointFor(args,{harness:args.harness.name,harnessSessionRef:args.harnessSessionId,generation:0},ctx),resume=(args,ctx)=>endpointFor(args,args.ref,ctx),park=async(_args,_ctx)=>{},close=async(_args,_ctx)=>{},health=async(_args,_ctx)=>({ok:!0,detail:"The session service watches the program it started"});export{REQUIRED_FINAL_EXTENSIONS,close,health,open,park,resume};\n';
2
+ export {
3
+ GENERAL_HARNESS_PROVIDER_SOURCE
4
+ };
5
+ //# sourceMappingURL=general.bundle.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/provider/general.bundle.ts"],
4
+ "sourcesContent": ["// Generated by scripts/bundle-provider.mjs from ./general.ts; do not edit.\nexport const GENERAL_HARNESS_PROVIDER_SOURCE =\n 'var RUNTIME_KINDS=[\"process\",\"worker\"];var ACP_V2_INTERFACE=\"acp-v2\";var PLACEHOLDER=/\\\\{\\\\{\\\\s*([A-Za-z0-9_.-]+)\\\\s*\\\\}\\\\}/gu,HARNESS_COMMAND_PATH=\"harness.command\",runtimesOf=run=>RUNTIME_KINDS.filter(kind=>run[kind]!=null),isRecord=value=>value!=null&&typeof value==\"object\"&&!Array.isArray(value),isJsonValue=value=>value===null||typeof value==\"string\"||typeof value==\"boolean\"?!0:typeof value==\"number\"?Number.isFinite(value):Array.isArray(value)?value.every(isJsonValue):isRecord(value)&&Object.values(value).every(isJsonValue),isJsonObject=value=>isRecord(value)&&isJsonValue(value),valueAt=(context,path)=>{if(path===HARNESS_COMMAND_PATH)return context.harness?.command;let value=context.configuration;for(let key of path.split(\".\").slice(1)){if(!isRecord(value))return;value=value[key]}return value},isSet=value=>value!=null&&value!==!1,textOf=value=>typeof value==\"string\"?value:JSON.stringify(value),render=(template,context,problems)=>template.replace(PLACEHOLDER,(_match,path)=>{let value=valueAt(context,path);return value==null?(problems.push(`{{${path}}} has no value`),\"\"):textOf(value)}),renderProcess=(run,context,problems)=>{let args=[];for(let arg of run.args)if(typeof arg==\"string\")args.push(render(arg,context,problems));else if(\"spread\"in arg)args.push(...context.harness?.args??[]);else if(isSet(valueAt(context,arg.when)))for(let template of arg.args)args.push(render(template,context,problems));let env={};for(let[key,value]of Object.entries(run.env))typeof value==\"string\"?env[key]=render(value,context,problems):isSet(valueAt(context,value.when))&&(env[key]=render(value.value,context,problems));return{command:render(run.command,context,problems),args,env}},harnessStartFor=args=>{let problems=[],{harness,adapter,configuration}=args;if(!isJsonObject(configuration))return{ok:!1,problems:[\"The configuration is not a JSON object\"]};if(args.runtime===\"process\"){let own2=harness.run.process,wrapper2=adapter==null?null:adapter.run.process;if(own2==null||adapter!=null&&wrapper2==null)return{ok:!1,problems:[\"No process entry to start\"]};let started=renderProcess(own2,{configuration,harness:null},problems),outer=wrapper2==null?started:renderProcess(wrapper2,{configuration,harness:{command:started.command,args:started.args}},problems),env=wrapper2==null?started.env:{...started.env,...outer.env};return problems.length>0?{ok:!1,problems}:{ok:!0,start:{runtime:\"process\",command:outer.command,args:outer.args,env}}}let own=harness.run.worker,wrapper=adapter==null?null:adapter.run.worker;return own==null||adapter!=null&&wrapper==null?{ok:!1,problems:[\"No worker entry to start\"]}:{ok:!0,start:{runtime:\"worker\",program:wrapper?.program??own.program,env:{},input:wrapper==null?{configuration}:{harness:{program:own.program},configuration}}}};var REQUIRED_FINAL_EXTENSIONS=[\"observe\",\"authorMeta\",\"resumeReplay\",\"afterSeqReplay\"],refused=problems=>({unsuitable:problems}),listOf=items=>items.length===0?\"nothing\":items.join(\", \"),urlEndpoint=async args=>{if(args.adapter!=null)return refused([`An ACP endpoint at a URL already speaks ACP and takes no adapter (${args.adapter})`]);let protocol;try{protocol=new URL(args.url).protocol}catch{return refused([`${args.url} is not a URL`])}let transport=protocol===\"wss:\"||protocol===\"ws:\"?\"ws\":protocol===\"https:\"||protocol===\"http:\"?\"http\":null;if(transport==null)return refused([`${args.url}: an ACP endpoint answers over ws(s) or http(s)`]);let headers={};if(args.hop!=null){let token=await args.ctx.secrets.get(args.hop);if(token==null||token.length===0)return refused([`The project has no secret ${args.hop} for ${args.url}`]);headers.authorization=`Bearer ${token}`}return{ref:args.ref,transport,url:args.url,headers,extensions:[...REQUIRED_FINAL_EXTENSIONS]}},sandboxEndpoint=(args,ref,sandboxId)=>{let harness=args.harness,adapter=args.adapter,name=harness.name;if(harness.definition.provider!=null)return refused([`${name} is reached by its own harness provider`]);let problems=[];if(adapter==null&&harness.definition.interface!==ACP_V2_INTERFACE&&problems.push(`${name} speaks ${harness.definition.interface}, not ACP v2, and has no adapter`),adapter!=null){adapter.definition.adapts.includes(harness.definition.interface)||problems.push(`ACP adapter ${adapter.name} adapts ${listOf(adapter.definition.adapts)}, not ${harness.definition.interface}`);let missing=REQUIRED_FINAL_EXTENSIONS.filter(extension=>!adapter.definition.extensions.includes(extension));missing.length>0&&problems.push(`ACP adapter ${adapter.name} does not implement Final\\'s ACP extensions ${listOf(missing)}`)}let runtime=args.runtime,harnessRuntimes=runtimesOf(harness.definition.run),adapterRuntimes=adapter==null?null:runtimesOf(adapter.definition.run);if(runtime==null?problems.push(`Sandbox ${sandboxId} runs nothing ${name} has an entry for`):(harnessRuntimes.includes(runtime)||problems.push(`${name} has no ${runtime} entry (it runs as ${listOf(harnessRuntimes)})`),adapter!=null&&adapterRuntimes!=null&&!adapterRuntimes.includes(runtime)&&problems.push(`ACP adapter ${adapter.name} has no ${runtime} entry (it runs as ${listOf(adapterRuntimes)})`)),problems.length>0||runtime==null)return refused(problems);let started=harnessStartFor({harness:harness.definition,adapter:adapter?.definition??null,runtime,configuration:args.settings.configuration});return started.ok?{ref,transport:\"sandbox\",sandboxId,start:started.start,extensions:[...REQUIRED_FINAL_EXTENSIONS]}:refused(started.problems)},endpointFor=(args,ref,ctx)=>{let environment=args.environment;return environment.kind===\"url\"?urlEndpoint({ref,url:environment.url,hop:environment.hop,adapter:args.adapter?.name??null,ctx}):Promise.resolve(sandboxEndpoint(args,ref,environment.sandboxId))},open=(args,ctx)=>endpointFor(args,{harness:args.harness.name,harnessSessionRef:args.harnessSessionId,generation:0},ctx),resume=(args,ctx)=>endpointFor(args,args.ref,ctx),park=async(_args,_ctx)=>{},close=async(_args,_ctx)=>{},health=async(_args,_ctx)=>({ok:!0,detail:\"The session service watches the program it started\"});export{REQUIRED_FINAL_EXTENSIONS,close,health,open,park,resume};\\n';\n"],
5
+ "mappings": "AACO,MAAM,kCACX;",
6
+ "names": []
7
+ }
@@ -0,0 +1,11 @@
1
+ import { FinalExtension } from '@finalai/agent-provider/harness-start';
2
+ import type { HarnessProviderCloseArgsIface, HarnessProviderContextIface, HarnessProviderOpenArgsIface, HarnessProviderOpenResultIface, HarnessProviderRefArgsIface, HarnessProviderResumeArgsIface } from '@finalai/agent-provider/harness-provider';
3
+ export declare const REQUIRED_FINAL_EXTENSIONS: readonly FinalExtension[];
4
+ export declare const open: (args: HarnessProviderOpenArgsIface, ctx: HarnessProviderContextIface) => Promise<HarnessProviderOpenResultIface>;
5
+ export declare const resume: (args: HarnessProviderResumeArgsIface, ctx: HarnessProviderContextIface) => Promise<HarnessProviderOpenResultIface>;
6
+ export declare const park: (_args: HarnessProviderRefArgsIface, _ctx: HarnessProviderContextIface) => Promise<void>;
7
+ export declare const close: (_args: HarnessProviderCloseArgsIface, _ctx: HarnessProviderContextIface) => Promise<void>;
8
+ export declare const health: (_args: HarnessProviderRefArgsIface, _ctx: HarnessProviderContextIface) => Promise<{
9
+ ok: boolean;
10
+ detail?: string;
11
+ }>;
@@ -0,0 +1,130 @@
1
+ import {
2
+ ACP_V2_INTERFACE,
3
+ FinalExtension,
4
+ harnessStartFor,
5
+ HarnessEnvironmentKind,
6
+ runtimesOf
7
+ } from "@finalai/agent-provider/harness-start";
8
+ const REQUIRED_FINAL_EXTENSIONS = [
9
+ FinalExtension.Observe,
10
+ FinalExtension.AuthorMeta,
11
+ FinalExtension.ResumeReplay,
12
+ FinalExtension.AfterSeqReplay
13
+ ];
14
+ const refused = (problems) => ({ unsuitable: problems });
15
+ const listOf = (items) => items.length === 0 ? "nothing" : items.join(", ");
16
+ const urlEndpoint = async (args) => {
17
+ if (args.adapter != null)
18
+ return refused([
19
+ `An ACP endpoint at a URL already speaks ACP and takes no adapter (${args.adapter})`
20
+ ]);
21
+ let protocol;
22
+ try {
23
+ protocol = new URL(args.url).protocol;
24
+ } catch {
25
+ return refused([`${args.url} is not a URL`]);
26
+ }
27
+ const transport = protocol === "wss:" || protocol === "ws:" ? "ws" : protocol === "https:" || protocol === "http:" ? "http" : null;
28
+ if (transport == null)
29
+ return refused([`${args.url}: an ACP endpoint answers over ws(s) or http(s)`]);
30
+ const headers = {};
31
+ if (args.hop != null) {
32
+ const token = await args.ctx.secrets.get(args.hop);
33
+ if (token == null || token.length === 0)
34
+ return refused([`The project has no secret ${args.hop} for ${args.url}`]);
35
+ headers["authorization"] = `Bearer ${token}`;
36
+ }
37
+ return {
38
+ ref: args.ref,
39
+ transport,
40
+ url: args.url,
41
+ headers,
42
+ extensions: [...REQUIRED_FINAL_EXTENSIONS]
43
+ };
44
+ };
45
+ const sandboxEndpoint = (args, ref, sandboxId) => {
46
+ const harness = args.harness;
47
+ const adapter = args.adapter;
48
+ const name = harness.name;
49
+ if (harness.definition.provider != null)
50
+ return refused([`${name} is reached by its own harness provider`]);
51
+ const problems = [];
52
+ if (adapter == null && harness.definition.interface !== ACP_V2_INTERFACE)
53
+ problems.push(`${name} speaks ${harness.definition.interface}, not ACP v2, and has no adapter`);
54
+ if (adapter != null) {
55
+ if (!adapter.definition.adapts.includes(harness.definition.interface))
56
+ problems.push(
57
+ `ACP adapter ${adapter.name} adapts ${listOf(adapter.definition.adapts)}, not ${harness.definition.interface}`
58
+ );
59
+ const missing = REQUIRED_FINAL_EXTENSIONS.filter(
60
+ (extension) => !adapter.definition.extensions.includes(extension)
61
+ );
62
+ if (missing.length > 0)
63
+ problems.push(
64
+ `ACP adapter ${adapter.name} does not implement Final's ACP extensions ${listOf(missing)}`
65
+ );
66
+ }
67
+ const runtime = args.runtime;
68
+ const harnessRuntimes = runtimesOf(harness.definition.run);
69
+ const adapterRuntimes = adapter == null ? null : runtimesOf(adapter.definition.run);
70
+ if (runtime == null) problems.push(`Sandbox ${sandboxId} runs nothing ${name} has an entry for`);
71
+ else {
72
+ if (!harnessRuntimes.includes(runtime))
73
+ problems.push(`${name} has no ${runtime} entry (it runs as ${listOf(harnessRuntimes)})`);
74
+ if (adapter != null && adapterRuntimes != null && !adapterRuntimes.includes(runtime))
75
+ problems.push(
76
+ `ACP adapter ${adapter.name} has no ${runtime} entry (it runs as ${listOf(adapterRuntimes)})`
77
+ );
78
+ }
79
+ if (problems.length > 0 || runtime == null) return refused(problems);
80
+ const started = harnessStartFor({
81
+ harness: harness.definition,
82
+ adapter: adapter?.definition ?? null,
83
+ runtime,
84
+ configuration: args.settings.configuration
85
+ });
86
+ if (!started.ok) return refused(started.problems);
87
+ const endpoint = {
88
+ ref,
89
+ transport: "sandbox",
90
+ sandboxId,
91
+ start: started.start,
92
+ extensions: [...REQUIRED_FINAL_EXTENSIONS]
93
+ };
94
+ return endpoint;
95
+ };
96
+ const endpointFor = (args, ref, ctx) => {
97
+ const environment = args.environment;
98
+ if (environment.kind === HarnessEnvironmentKind.Url)
99
+ return urlEndpoint({
100
+ ref,
101
+ url: environment.url,
102
+ hop: environment.hop,
103
+ adapter: args.adapter?.name ?? null,
104
+ ctx
105
+ });
106
+ return Promise.resolve(sandboxEndpoint(args, ref, environment.sandboxId));
107
+ };
108
+ const open = (args, ctx) => endpointFor(
109
+ args,
110
+ { harness: args.harness.name, harnessSessionRef: args.harnessSessionId, generation: 0 },
111
+ ctx
112
+ );
113
+ const resume = (args, ctx) => endpointFor(args, args.ref, ctx);
114
+ const park = async (_args, _ctx) => {
115
+ };
116
+ const close = async (_args, _ctx) => {
117
+ };
118
+ const health = async (_args, _ctx) => ({
119
+ ok: true,
120
+ detail: "The session service watches the program it started"
121
+ });
122
+ export {
123
+ REQUIRED_FINAL_EXTENSIONS,
124
+ close,
125
+ health,
126
+ open,
127
+ park,
128
+ resume
129
+ };
130
+ //# sourceMappingURL=general.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/provider/general.ts"],
4
+ "sourcesContent": ["import type { HarnessSessionRefIface } from '@finalai/agent-provider/harness';\nimport type { ComposedEnvironmentIface } from '@finalai/agent-provider/harness-definition';\nimport {\n ACP_V2_INTERFACE,\n FinalExtension,\n harnessStartFor,\n HarnessEnvironmentKind,\n runtimesOf,\n} from '@finalai/agent-provider/harness-start';\nimport type {\n HarnessProviderCloseArgsIface,\n HarnessProviderContextIface,\n HarnessProviderEndpointResultIface,\n HarnessProviderOpenArgsIface,\n HarnessProviderOpenResultIface,\n HarnessProviderRefArgsIface,\n HarnessProviderResumeArgsIface,\n} from '@finalai/agent-provider/harness-provider';\n\n// The general harness provider: it starts adapter(harness) in the harness's\n// environment from the two definitions' run entries and hands the session\n// service the ACP stream; for an environment at a URL it hands over the URL.\n// Built only on the public harness provider contract and bundled into one\n// self-contained module (./general.bundle.ts), like any third party's\n// provider. It imports values only from dependency-free modules, and writes\n// the contract's transports as the strings they are, to keep that small.\n//\n// The session service starts what a `sandbox` endpoint names over the\n// sandbox's process streams (startSandboxEndpoint) and keeps the program for\n// the session's life, so park, close and health have nothing of their own to\n// stop or watch.\n\n// What every ACP endpoint it hands over must implement and advertise in\n// `initialize`, beyond ACP v2.\nexport const REQUIRED_FINAL_EXTENSIONS: readonly FinalExtension[] = [\n FinalExtension.Observe,\n FinalExtension.AuthorMeta,\n FinalExtension.ResumeReplay,\n FinalExtension.AfterSeqReplay,\n];\n\nconst refused = (problems: string[]): HarnessProviderOpenResultIface => ({ unsuitable: problems });\n\nconst listOf = (items: readonly string[]): string =>\n items.length === 0 ? 'nothing' : items.join(', ');\n\nconst urlEndpoint = async (args: {\n ref: HarnessSessionRefIface;\n url: string;\n hop: string | null;\n adapter: string | null;\n ctx: HarnessProviderContextIface;\n}): Promise<HarnessProviderOpenResultIface> => {\n if (args.adapter != null)\n return refused([\n `An ACP endpoint at a URL already speaks ACP and takes no adapter (${args.adapter})`,\n ]);\n let protocol: string;\n try {\n protocol = new URL(args.url).protocol;\n } catch {\n return refused([`${args.url} is not a URL`]);\n }\n const transport =\n protocol === 'wss:' || protocol === 'ws:'\n ? 'ws'\n : protocol === 'https:' || protocol === 'http:'\n ? 'http'\n : null;\n if (transport == null)\n return refused([`${args.url}: an ACP endpoint answers over ws(s) or http(s)`]);\n const headers: Record<string, string> = {};\n if (args.hop != null) {\n const token = await args.ctx.secrets.get(args.hop);\n if (token == null || token.length === 0)\n return refused([`The project has no secret ${args.hop} for ${args.url}`]);\n headers['authorization'] = `Bearer ${token}`;\n }\n return {\n ref: args.ref,\n transport,\n url: args.url,\n headers,\n extensions: [...REQUIRED_FINAL_EXTENSIONS],\n };\n};\n\nconst sandboxEndpoint = (\n args: HarnessProviderOpenArgsIface,\n ref: HarnessSessionRefIface,\n sandboxId: string,\n): HarnessProviderOpenResultIface => {\n const harness = args.harness;\n const adapter = args.adapter;\n const name = harness.name;\n if (harness.definition.provider != null)\n return refused([`${name} is reached by its own harness provider`]);\n const problems: string[] = [];\n if (adapter == null && harness.definition.interface !== ACP_V2_INTERFACE)\n problems.push(`${name} speaks ${harness.definition.interface}, not ACP v2, and has no adapter`);\n if (adapter != null) {\n if (!adapter.definition.adapts.includes(harness.definition.interface))\n problems.push(\n `ACP adapter ${adapter.name} adapts ${listOf(adapter.definition.adapts)}, not ${harness.definition.interface}`,\n );\n const missing = REQUIRED_FINAL_EXTENSIONS.filter(\n (extension) => !adapter.definition.extensions.includes(extension),\n );\n if (missing.length > 0)\n problems.push(\n `ACP adapter ${adapter.name} does not implement Final's ACP extensions ${listOf(missing)}`,\n );\n }\n const runtime = args.runtime;\n const harnessRuntimes = runtimesOf(harness.definition.run);\n const adapterRuntimes = adapter == null ? null : runtimesOf(adapter.definition.run);\n if (runtime == null) problems.push(`Sandbox ${sandboxId} runs nothing ${name} has an entry for`);\n else {\n if (!harnessRuntimes.includes(runtime))\n problems.push(`${name} has no ${runtime} entry (it runs as ${listOf(harnessRuntimes)})`);\n if (adapter != null && adapterRuntimes != null && !adapterRuntimes.includes(runtime))\n problems.push(\n `ACP adapter ${adapter.name} has no ${runtime} entry (it runs as ${listOf(adapterRuntimes)})`,\n );\n }\n if (problems.length > 0 || runtime == null) return refused(problems);\n\n const started = harnessStartFor({\n harness: harness.definition,\n adapter: adapter?.definition ?? null,\n runtime,\n configuration: args.settings.configuration,\n });\n if (!started.ok) return refused(started.problems);\n const endpoint: HarnessProviderEndpointResultIface = {\n ref,\n transport: 'sandbox',\n sandboxId,\n start: started.start,\n extensions: [...REQUIRED_FINAL_EXTENSIONS],\n };\n return endpoint;\n};\n\nconst endpointFor = (\n args: HarnessProviderOpenArgsIface,\n ref: HarnessSessionRefIface,\n ctx: HarnessProviderContextIface,\n): Promise<HarnessProviderOpenResultIface> => {\n const environment: ComposedEnvironmentIface = args.environment;\n if (environment.kind === HarnessEnvironmentKind.Url)\n return urlEndpoint({\n ref,\n url: environment.url,\n hop: environment.hop,\n adapter: args.adapter?.name ?? null,\n ctx,\n });\n return Promise.resolve(sandboxEndpoint(args, ref, environment.sandboxId));\n};\n\nexport const open = (\n args: HarnessProviderOpenArgsIface,\n ctx: HarnessProviderContextIface,\n): Promise<HarnessProviderOpenResultIface> =>\n endpointFor(\n args,\n { harness: args.harness.name, harnessSessionRef: args.harnessSessionId, generation: 0 },\n ctx,\n );\n\n// The worker runtime finds a harness session's state again by its id; a\n// process starts afresh and the session service resumes it over ACP.\nexport const resume = (\n args: HarnessProviderResumeArgsIface,\n ctx: HarnessProviderContextIface,\n): Promise<HarnessProviderOpenResultIface> => endpointFor(args, args.ref, ctx);\n\nexport const park = async (\n _args: HarnessProviderRefArgsIface,\n _ctx: HarnessProviderContextIface,\n): Promise<void> => {};\n\nexport const close = async (\n _args: HarnessProviderCloseArgsIface,\n _ctx: HarnessProviderContextIface,\n): Promise<void> => {};\n\nexport const health = async (\n _args: HarnessProviderRefArgsIface,\n _ctx: HarnessProviderContextIface,\n): Promise<{ ok: boolean; detail?: string }> => ({\n ok: true,\n detail: 'The session service watches the program it started',\n});\n"],
5
+ "mappings": "AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AA0BA,MAAM,4BAAuD;AAAA,EAClE,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AACjB;AAEA,MAAM,UAAU,CAAC,cAAwD,EAAE,YAAY,SAAS;AAEhG,MAAM,SAAS,CAAC,UACd,MAAM,WAAW,IAAI,YAAY,MAAM,KAAK,IAAI;AAElD,MAAM,cAAc,OAAO,SAMoB;AAC7C,MAAI,KAAK,WAAW;AAClB,WAAO,QAAQ;AAAA,MACb,qEAAqE,KAAK,OAAO;AAAA,IACnF,CAAC;AACH,MAAI;AACJ,MAAI;AACF,eAAW,IAAI,IAAI,KAAK,GAAG,EAAE;AAAA,EAC/B,QAAQ;AACN,WAAO,QAAQ,CAAC,GAAG,KAAK,GAAG,eAAe,CAAC;AAAA,EAC7C;AACA,QAAM,YACJ,aAAa,UAAU,aAAa,QAChC,OACA,aAAa,YAAY,aAAa,UACpC,SACA;AACR,MAAI,aAAa;AACf,WAAO,QAAQ,CAAC,GAAG,KAAK,GAAG,iDAAiD,CAAC;AAC/E,QAAM,UAAkC,CAAC;AACzC,MAAI,KAAK,OAAO,MAAM;AACpB,UAAM,QAAQ,MAAM,KAAK,IAAI,QAAQ,IAAI,KAAK,GAAG;AACjD,QAAI,SAAS,QAAQ,MAAM,WAAW;AACpC,aAAO,QAAQ,CAAC,6BAA6B,KAAK,GAAG,QAAQ,KAAK,GAAG,EAAE,CAAC;AAC1E,YAAQ,eAAe,IAAI,UAAU,KAAK;AAAA,EAC5C;AACA,SAAO;AAAA,IACL,KAAK,KAAK;AAAA,IACV;AAAA,IACA,KAAK,KAAK;AAAA,IACV;AAAA,IACA,YAAY,CAAC,GAAG,yBAAyB;AAAA,EAC3C;AACF;AAEA,MAAM,kBAAkB,CACtB,MACA,KACA,cACmC;AACnC,QAAM,UAAU,KAAK;AACrB,QAAM,UAAU,KAAK;AACrB,QAAM,OAAO,QAAQ;AACrB,MAAI,QAAQ,WAAW,YAAY;AACjC,WAAO,QAAQ,CAAC,GAAG,IAAI,yCAAyC,CAAC;AACnE,QAAM,WAAqB,CAAC;AAC5B,MAAI,WAAW,QAAQ,QAAQ,WAAW,cAAc;AACtD,aAAS,KAAK,GAAG,IAAI,WAAW,QAAQ,WAAW,SAAS,kCAAkC;AAChG,MAAI,WAAW,MAAM;AACnB,QAAI,CAAC,QAAQ,WAAW,OAAO,SAAS,QAAQ,WAAW,SAAS;AAClE,eAAS;AAAA,QACP,eAAe,QAAQ,IAAI,WAAW,OAAO,QAAQ,WAAW,MAAM,CAAC,SAAS,QAAQ,WAAW,SAAS;AAAA,MAC9G;AACF,UAAM,UAAU,0BAA0B;AAAA,MACxC,CAAC,cAAc,CAAC,QAAQ,WAAW,WAAW,SAAS,SAAS;AAAA,IAClE;AACA,QAAI,QAAQ,SAAS;AACnB,eAAS;AAAA,QACP,eAAe,QAAQ,IAAI,8CAA8C,OAAO,OAAO,CAAC;AAAA,MAC1F;AAAA,EACJ;AACA,QAAM,UAAU,KAAK;AACrB,QAAM,kBAAkB,WAAW,QAAQ,WAAW,GAAG;AACzD,QAAM,kBAAkB,WAAW,OAAO,OAAO,WAAW,QAAQ,WAAW,GAAG;AAClF,MAAI,WAAW,KAAM,UAAS,KAAK,WAAW,SAAS,iBAAiB,IAAI,mBAAmB;AAAA,OAC1F;AACH,QAAI,CAAC,gBAAgB,SAAS,OAAO;AACnC,eAAS,KAAK,GAAG,IAAI,WAAW,OAAO,sBAAsB,OAAO,eAAe,CAAC,GAAG;AACzF,QAAI,WAAW,QAAQ,mBAAmB,QAAQ,CAAC,gBAAgB,SAAS,OAAO;AACjF,eAAS;AAAA,QACP,eAAe,QAAQ,IAAI,WAAW,OAAO,sBAAsB,OAAO,eAAe,CAAC;AAAA,MAC5F;AAAA,EACJ;AACA,MAAI,SAAS,SAAS,KAAK,WAAW,KAAM,QAAO,QAAQ,QAAQ;AAEnE,QAAM,UAAU,gBAAgB;AAAA,IAC9B,SAAS,QAAQ;AAAA,IACjB,SAAS,SAAS,cAAc;AAAA,IAChC;AAAA,IACA,eAAe,KAAK,SAAS;AAAA,EAC/B,CAAC;AACD,MAAI,CAAC,QAAQ,GAAI,QAAO,QAAQ,QAAQ,QAAQ;AAChD,QAAM,WAA+C;AAAA,IACnD;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA,OAAO,QAAQ;AAAA,IACf,YAAY,CAAC,GAAG,yBAAyB;AAAA,EAC3C;AACA,SAAO;AACT;AAEA,MAAM,cAAc,CAClB,MACA,KACA,QAC4C;AAC5C,QAAM,cAAwC,KAAK;AACnD,MAAI,YAAY,SAAS,uBAAuB;AAC9C,WAAO,YAAY;AAAA,MACjB;AAAA,MACA,KAAK,YAAY;AAAA,MACjB,KAAK,YAAY;AAAA,MACjB,SAAS,KAAK,SAAS,QAAQ;AAAA,MAC/B;AAAA,IACF,CAAC;AACH,SAAO,QAAQ,QAAQ,gBAAgB,MAAM,KAAK,YAAY,SAAS,CAAC;AAC1E;AAEO,MAAM,OAAO,CAClB,MACA,QAEA;AAAA,EACE;AAAA,EACA,EAAE,SAAS,KAAK,QAAQ,MAAM,mBAAmB,KAAK,kBAAkB,YAAY,EAAE;AAAA,EACtF;AACF;AAIK,MAAM,SAAS,CACpB,MACA,QAC4C,YAAY,MAAM,KAAK,KAAK,GAAG;AAEtE,MAAM,OAAO,OAClB,OACA,SACkB;AAAC;AAEd,MAAM,QAAQ,OACnB,OACA,SACkB;AAAC;AAEd,MAAM,SAAS,OACpB,OACA,UAC+C;AAAA,EAC/C,IAAI;AAAA,EACJ,QAAQ;AACV;",
6
+ "names": []
7
+ }
@@ -0,0 +1,3 @@
1
+ import { type DefinedHarnessProviderIface } from '@finalai/agent-definition/authoring';
2
+ export { REQUIRED_FINAL_EXTENSIONS } from "./general.mjs";
3
+ export declare const GENERAL_HARNESS_PROVIDER: DefinedHarnessProviderIface;