@finalai/agent-definition 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HOSTING.md +49 -9
- package/dist/compiler-assets/{chunk-RIEMTCTV.ts → chunk-5PWY25HA.ts} +3 -2
- package/dist/compiler-assets/{chunk-Z5TO7RSJ.ts → chunk-RSWGFPNZ.ts} +1 -1
- package/dist/compiler-assets/src/authoring/harness.ts +2 -2
- package/dist/compiler-assets/src/authoring/index.ts +3 -3
- package/dist/compiler-assets/src/authoring/sandbox.ts +2 -2
- package/dist/compiler-assets/src/compatibility.ts +1 -1
- package/dist/compiler-assets/src/index.ts +3 -3
- package/dist/modules/authoring/connections.mjs.map +2 -2
- package/fixtures/release-scout/agent/sandbox.ts +1 -1
- package/package.json +2 -2
- /package/dist/compiler-assets/{chunk-IZGOMT7K.ts → chunk-B5RJDCXZ.ts} +0 -0
package/HOSTING.md
CHANGED
|
@@ -21,6 +21,24 @@ Neither rewrites authored URLs. A GitHub-backed definition uses remote source;
|
|
|
21
21
|
push edits before explicitly publishing a ref. Caller API keys never become agent
|
|
22
22
|
credentials merely because they were used to publish.
|
|
23
23
|
|
|
24
|
+
## Hosted model resolution (SDK 0.2.0)
|
|
25
|
+
|
|
26
|
+
Hosted Final, Pi, Codex and Claude configurations accept string model references.
|
|
27
|
+
`serverless*ConfigSchema.parse(...).model` can be undefined: the host must choose
|
|
28
|
+
its catalog default, resolve aliases and validate availability before dispatch.
|
|
29
|
+
The host owns current candidates, runtime capabilities and dated prices, and
|
|
30
|
+
advertises picker choices through its harness descriptions. Compilation remains
|
|
31
|
+
offline and checks reference syntax.
|
|
32
|
+
|
|
33
|
+
SDK 0.2.0 removes `@finalai/agents/models` and
|
|
34
|
+
`@finalai/final-agent-provider/harnesses/models`, including their model arrays,
|
|
35
|
+
defaults, model-ID unions and pricing helpers. Migrate callers to string model
|
|
36
|
+
references and host-owned discovery, metadata and pricing.
|
|
37
|
+
|
|
38
|
+
Publish the SDK release before upgrading host dependencies. Ship the host's
|
|
39
|
+
catalog/default implementation together with its SDK dependency upgrade; a host
|
|
40
|
+
that only changes the dependency will lose the old default and catalog APIs.
|
|
41
|
+
|
|
24
42
|
## Hosted connections
|
|
25
43
|
|
|
26
44
|
```ts
|
|
@@ -99,15 +117,37 @@ export default defineFinalConnection({
|
|
|
99
117
|
});
|
|
100
118
|
```
|
|
101
119
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
120
|
+
With `load`, the host lists only the loaded tools and must keep every other exposed
|
|
121
|
+
tool reachable: it serves a search over the connection's remaining exposed tools
|
|
122
|
+
(name, description, input schema) and a call that runs a found tool by its real
|
|
123
|
+
name, with the same exposure and approval checks as a direct call. A host may
|
|
124
|
+
instead add a found tool to the list and send `notifications/tools/list_changed`;
|
|
125
|
+
harnesses that ignore that notification still need the call path. `load: []`
|
|
126
|
+
leaves every tool to search. Entries are tool names or `*` patterns.
|
|
127
|
+
`isToolLoaded` from `@finalai/agent-provider` applies the rule after exposure.
|
|
128
|
+
|
|
129
|
+
Without `load`, the harness lists the connection's exposed tools except:
|
|
130
|
+
|
|
131
|
+
- **Connector tools.** A server can label a tool with the connector it belongs to
|
|
132
|
+
in the tool's `_meta`:
|
|
133
|
+
`{ "ai.final/connector": { "namespace": "salesforce", "name": "Salesforce" } }`.
|
|
134
|
+
The namespace identifies the connector (unique within the server's tools); the
|
|
135
|
+
name is for display, and two connectors may share one. Final's server labels
|
|
136
|
+
every connector tool with the namespace and name of the install it comes from.
|
|
137
|
+
The host never lists labelled tools up front. Its search tool names each
|
|
138
|
+
connector and how many tools it has, so the agent knows what is connected
|
|
139
|
+
without any of those definitions in its context, and searches for the tools it
|
|
140
|
+
needs. A `load` entry that names a labelled tool still lists it.
|
|
141
|
+
- **Tools past a size limit.** When a connection exposes more unlabelled tools
|
|
142
|
+
than the host lists directly (100 in Final's host), those are searched too.
|
|
143
|
+
|
|
144
|
+
A harness that declares `supports.deferredToolSearch` defers and searches tools
|
|
145
|
+
itself, so the host lists every exposed tool to it and serves no search.
|
|
146
|
+
|
|
147
|
+
A host's search should name the connectors it covers and accept a connector's
|
|
148
|
+
namespace to narrow to. Once a host has listed its search and call tools, it keeps answering them for
|
|
149
|
+
that harness even if the connection stops hiding tools, unless the connection
|
|
150
|
+
then lists its own tool by one of those names.
|
|
111
151
|
|
|
112
152
|
## Selecting tools by annotation
|
|
113
153
|
|
|
@@ -68,7 +68,7 @@ var SHARED_SCHEMAS = {
|
|
|
68
68
|
[SCHEMA_IDS.modelPicker]: {
|
|
69
69
|
$id: SCHEMA_IDS.modelPicker,
|
|
70
70
|
title: "Model",
|
|
71
|
-
// The harness
|
|
71
|
+
// The harness or hosting platform supplies reference constraints and picker choices.
|
|
72
72
|
type: "string",
|
|
73
73
|
"x-final-widget": "model-picker"
|
|
74
74
|
},
|
|
@@ -263,7 +263,8 @@ var harnessDescriptionSchema = object({
|
|
|
263
263
|
nativeToolPolicy: boolean().optional(),
|
|
264
264
|
// Defers and searches MCP tools itself (a harness-native tool search): the
|
|
265
265
|
// host lists every exposed tool, ignoring connections' `tools.load`, and
|
|
266
|
-
// adds no search of its own. Absent: the host
|
|
266
|
+
// adds no search of its own. Absent: the host lists what `load` (or, without
|
|
267
|
+
// it, HOSTING.md's defaults) leaves listed and serves search for the rest.
|
|
267
268
|
deferredToolSearch: boolean().optional()
|
|
268
269
|
}),
|
|
269
270
|
promptWhileRunning: nativeEnum(PromptWhileRunning).default(DEFAULT_PROMPT_WHILE_RUNNING),
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
completeHarnessDescription,
|
|
3
3
|
defineHarness
|
|
4
|
-
} from "../../chunk-
|
|
5
|
-
import "../../chunk-
|
|
4
|
+
} from "../../chunk-RSWGFPNZ.ts";
|
|
5
|
+
import "../../chunk-5PWY25HA.ts";
|
|
6
6
|
import "../../chunk-APU2VKLW.ts";
|
|
7
7
|
import "../../chunk-GCFSHHH2.ts";
|
|
8
8
|
import "../../chunk-MSE7X5YG.ts";
|
|
@@ -2,7 +2,7 @@ import "../../chunk-RMIQJHSL.ts";
|
|
|
2
2
|
import {
|
|
3
3
|
completeHarnessDescription,
|
|
4
4
|
defineHarness
|
|
5
|
-
} from "../../chunk-
|
|
5
|
+
} from "../../chunk-RSWGFPNZ.ts";
|
|
6
6
|
import {
|
|
7
7
|
HookEvent,
|
|
8
8
|
defineHook
|
|
@@ -15,11 +15,11 @@ import {
|
|
|
15
15
|
defineSandbox,
|
|
16
16
|
defineSandboxProvider,
|
|
17
17
|
harnessHost
|
|
18
|
-
} from "../../chunk-
|
|
18
|
+
} from "../../chunk-B5RJDCXZ.ts";
|
|
19
19
|
import "../../chunk-4E5HECVD.ts";
|
|
20
20
|
import {
|
|
21
21
|
SandboxWire
|
|
22
|
-
} from "../../chunk-
|
|
22
|
+
} from "../../chunk-5PWY25HA.ts";
|
|
23
23
|
import {
|
|
24
24
|
defineSchedule
|
|
25
25
|
} from "../../chunk-JGQ2KAN7.ts";
|
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
defineSandbox,
|
|
4
4
|
defineSandboxProvider,
|
|
5
5
|
harnessHost
|
|
6
|
-
} from "../../chunk-
|
|
6
|
+
} from "../../chunk-B5RJDCXZ.ts";
|
|
7
7
|
import "../../chunk-4E5HECVD.ts";
|
|
8
8
|
import {
|
|
9
9
|
SandboxWire
|
|
10
|
-
} from "../../chunk-
|
|
10
|
+
} from "../../chunk-5PWY25HA.ts";
|
|
11
11
|
import "../../chunk-APU2VKLW.ts";
|
|
12
12
|
import "../../chunk-GCFSHHH2.ts";
|
|
13
13
|
import "../../chunk-MSE7X5YG.ts";
|
|
@@ -15,7 +15,7 @@ import "../chunk-RMIQJHSL.ts";
|
|
|
15
15
|
import {
|
|
16
16
|
completeHarnessDescription,
|
|
17
17
|
defineHarness
|
|
18
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-RSWGFPNZ.ts";
|
|
19
19
|
import {
|
|
20
20
|
HookEvent,
|
|
21
21
|
defineHook
|
|
@@ -28,11 +28,11 @@ import {
|
|
|
28
28
|
defineSandbox,
|
|
29
29
|
defineSandboxProvider,
|
|
30
30
|
harnessHost
|
|
31
|
-
} from "../chunk-
|
|
31
|
+
} from "../chunk-B5RJDCXZ.ts";
|
|
32
32
|
import "../chunk-4E5HECVD.ts";
|
|
33
33
|
import {
|
|
34
34
|
SandboxWire
|
|
35
|
-
} from "../chunk-
|
|
35
|
+
} from "../chunk-5PWY25HA.ts";
|
|
36
36
|
import {
|
|
37
37
|
defineSchedule
|
|
38
38
|
} from "../chunk-JGQ2KAN7.ts";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/authoring/connections.ts"],
|
|
4
|
-
"sourcesContent": ["import type { ApprovalPolicyIface } from \"./approval.mjs\";\nimport { AuthoredKind, stamp } from \"./brand.mjs\";\nimport { jsonObjectSchema, mcpAuthSchema, requireHostedBinding } from '@finalai/agent-provider';\nimport * as z from 'zod';\nimport { defineDynamic, type DynamicSentinelIface } from \"./dynamic.mjs\";\n\n// An MCP connection. Secrets are references by\n// name: the MCP host injects them, so they never reach the harness. Final's\n// own MCP server is an ordinary connection with `auth: { kind: 'final-session' }`.\n\nexport type McpConnectionAuthIface =\n // Sent as `Authorization: Bearer <secret>` when headerName is null.\n | { readonly secretKey: string; readonly headerName: string | null }\n | { readonly kind: 'final-session' };\n\n// Selects tools by the MCP annotations their server reports, reading omitted\n// hints as the spec's defaults: `{ readOnlyHint: true }` matches only tools\n// the server marks read-only. Use with servers you trust to classify tools.\nexport interface McpToolAnnotationSelectorIface {\n readonly readOnlyHint?: boolean;\n readonly destructiveHint?: boolean;\n readonly idempotentHint?: boolean;\n readonly openWorldHint?: boolean;\n}\n\nexport type McpToolSelector = string | McpToolAnnotationSelectorIface;\n\n// Entries and keys are tool names or `*` patterns (`github.*`), and allow and\n// deny entries may also be annotation selectors; the most specific matching\n// key governs a tool.\nexport interface McpConnectionToolsIface {\n // Only these tools are exposed; omit to expose every tool the server lists.\n // Annotation-selected tools run under the connection's default approval.\n readonly allow?: readonly McpToolSelector[];\n // These tools are hidden, whatever `allow` says.\n readonly deny?: readonly McpToolSelector[];\n // Per-tool approval; tools not listed use the connection's `approval`.\n readonly approval?: Readonly<Record<string, ApprovalPolicyIface<never>>>;\n // Exposed tools (names or `*` patterns) the harness lists up front; the rest\n // stay reachable through the host's tool search.
|
|
5
|
-
"mappings": "AACA,SAAS,cAAc,aAAa;AACpC,SAAS,kBAAkB,eAAe,4BAA4B;AACtE,YAAY,OAAO;AACnB,SAAS,qBAAgD;
|
|
4
|
+
"sourcesContent": ["import type { ApprovalPolicyIface } from \"./approval.mjs\";\nimport { AuthoredKind, stamp } from \"./brand.mjs\";\nimport { jsonObjectSchema, mcpAuthSchema, requireHostedBinding } from '@finalai/agent-provider';\nimport * as z from 'zod';\nimport { defineDynamic, type DynamicSentinelIface } from \"./dynamic.mjs\";\n\n// An MCP connection. Secrets are references by\n// name: the MCP host injects them, so they never reach the harness. Final's\n// own MCP server is an ordinary connection with `auth: { kind: 'final-session' }`.\n\nexport type McpConnectionAuthIface =\n // Sent as `Authorization: Bearer <secret>` when headerName is null.\n | { readonly secretKey: string; readonly headerName: string | null }\n | { readonly kind: 'final-session' };\n\n// Selects tools by the MCP annotations their server reports, reading omitted\n// hints as the spec's defaults: `{ readOnlyHint: true }` matches only tools\n// the server marks read-only. Use with servers you trust to classify tools.\nexport interface McpToolAnnotationSelectorIface {\n readonly readOnlyHint?: boolean;\n readonly destructiveHint?: boolean;\n readonly idempotentHint?: boolean;\n readonly openWorldHint?: boolean;\n}\n\nexport type McpToolSelector = string | McpToolAnnotationSelectorIface;\n\n// Entries and keys are tool names or `*` patterns (`github.*`), and allow and\n// deny entries may also be annotation selectors; the most specific matching\n// key governs a tool.\nexport interface McpConnectionToolsIface {\n // Only these tools are exposed; omit to expose every tool the server lists.\n // Annotation-selected tools run under the connection's default approval.\n readonly allow?: readonly McpToolSelector[];\n // These tools are hidden, whatever `allow` says.\n readonly deny?: readonly McpToolSelector[];\n // Per-tool approval; tools not listed use the connection's `approval`.\n readonly approval?: Readonly<Record<string, ApprovalPolicyIface<never>>>;\n // Exposed tools (names or `*` patterns) the harness lists up front; the rest\n // stay reachable through the host's tool search. Omitted, the harness lists\n // every exposed tool except connector tools and tools past the\n // host's size limit (HOSTING.md \"Loaded and searchable tools\").\n readonly load?: readonly string[];\n}\n\nexport interface McpClientConnectionDefinitionIface {\n readonly url: string;\n readonly description?: string;\n readonly auth?: McpConnectionAuthIface;\n readonly headers?: Readonly<Record<string, string>>;\n readonly tools?: McpConnectionToolsIface;\n // Default approval for every tool of this connection.\n readonly approval?: ApprovalPolicyIface<never>;\n readonly protocolVersionDiscovery?: boolean;\n readonly instanceKey?: string;\n}\n\nexport const defineMcpClientConnection = <TConnection extends McpClientConnectionDefinitionIface>(\n definition: TConnection,\n): TConnection => stamp({ ...definition }, AuthoredKind.Connection);\n\nexport interface HostedConnectionDefinitionIface extends Omit<\n McpClientConnectionDefinitionIface,\n 'url' | 'auth' | 'headers' | 'protocolVersionDiscovery' | 'instanceKey'\n> {\n readonly binding: string;\n}\n\nconst hostedConnectionSchema = z.strictObject({\n url: z.string().url(),\n auth: mcpAuthSchema.nullable().optional(),\n headers: z.record(z.string(), z.string()).optional(),\n});\n\n// Built-in and third-party bindings use the ordinary dynamic connection path.\nexport const defineHostedConnection = (\n definition: HostedConnectionDefinitionIface,\n): DynamicSentinelIface<McpClientConnectionDefinitionIface> => {\n const { binding, description, tools, approval } = definition;\n if (binding.trim().length === 0) throw new Error('Hosted connection binding must not be empty');\n return defineDynamic({\n description: definition.description ?? `Hosted connection ${binding}`,\n preview: `Resolved by hosting from ${binding}`,\n requiredBindings: [\n { name: binding, schema: jsonObjectSchema.parse(z.toJSONSchema(hostedConnectionSchema)) },\n ],\n events: {\n 'session.started': async (_event, ctx) => {\n const value = await requireHostedBinding({ bindings: ctx.bindings, name: binding });\n const parsed = hostedConnectionSchema.safeParse(value);\n if (!parsed.success)\n throw new Error(`Hosted connection ${binding} has invalid configuration`);\n const { auth, ...transport } = parsed.data;\n return defineMcpClientConnection({\n ...transport,\n description,\n tools,\n approval,\n ...(auth == null ? {} : { auth }),\n });\n },\n },\n });\n};\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,cAAc,aAAa;AACpC,SAAS,kBAAkB,eAAe,4BAA4B;AACtE,YAAY,OAAO;AACnB,SAAS,qBAAgD;AAqDlD,MAAM,4BAA4B,CACvC,eACgB,MAAM,EAAE,GAAG,WAAW,GAAG,aAAa,UAAU;AASlE,MAAM,yBAAyB,EAAE,aAAa;AAAA,EAC5C,KAAK,EAAE,OAAO,EAAE,IAAI;AAAA,EACpB,MAAM,cAAc,SAAS,EAAE,SAAS;AAAA,EACxC,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,EAAE,SAAS;AACrD,CAAC;AAGM,MAAM,yBAAyB,CACpC,eAC6D;AAC7D,QAAM,EAAE,SAAS,aAAa,OAAO,SAAS,IAAI;AAClD,MAAI,QAAQ,KAAK,EAAE,WAAW,EAAG,OAAM,IAAI,MAAM,6CAA6C;AAC9F,SAAO,cAAc;AAAA,IACnB,aAAa,WAAW,eAAe,qBAAqB,OAAO;AAAA,IACnE,SAAS,4BAA4B,OAAO;AAAA,IAC5C,kBAAkB;AAAA,MAChB,EAAE,MAAM,SAAS,QAAQ,iBAAiB,MAAM,EAAE,aAAa,sBAAsB,CAAC,EAAE;AAAA,IAC1F;AAAA,IACA,QAAQ;AAAA,MACN,mBAAmB,OAAO,QAAQ,QAAQ;AACxC,cAAM,QAAQ,MAAM,qBAAqB,EAAE,UAAU,IAAI,UAAU,MAAM,QAAQ,CAAC;AAClF,cAAM,SAAS,uBAAuB,UAAU,KAAK;AACrD,YAAI,CAAC,OAAO;AACV,gBAAM,IAAI,MAAM,qBAAqB,OAAO,4BAA4B;AAC1E,cAAM,EAAE,MAAM,GAAG,UAAU,IAAI,OAAO;AACtC,eAAO,0BAA0B;AAAA,UAC/B,GAAG;AAAA,UACH;AAAA,UACA;AAAA,UACA;AAAA,UACA,GAAI,QAAQ,OAAO,CAAC,IAAI,EAAE,KAAK;AAAA,QACjC,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC;AACH;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -7,7 +7,7 @@ export const computer = computerSetupGuide({
|
|
|
7
7
|
ref: 'release-scout-dev',
|
|
8
8
|
version: 'latest',
|
|
9
9
|
repositories: [{ alias: 'app', repository: 'final/app', ref: 'main' }],
|
|
10
|
-
variables: ['
|
|
10
|
+
variables: ['NPM_TOKEN'],
|
|
11
11
|
workspace: 'session',
|
|
12
12
|
networkPolicy: 'allow-all',
|
|
13
13
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@finalai/agent-definition",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Provider-independent agent authoring, manifest schemas, directory compiler, and harness compatibility reports.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
},
|
|
77
77
|
"dependencies": {
|
|
78
78
|
"@finalai/agent-protocol": "0.1.4",
|
|
79
|
-
"@finalai/agent-provider": "0.1.
|
|
79
|
+
"@finalai/agent-provider": "0.1.6",
|
|
80
80
|
"ajv": "^8.20.0",
|
|
81
81
|
"ajv-formats": "^3.0.1",
|
|
82
82
|
"croner": "^10.0.1",
|
|
File without changes
|