@finalai/agents 0.9.0 → 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.
- package/HOSTING.md +3 -3
- package/README.md +5 -1
- package/dist/modules/agent-client/build.d.mts +2 -1
- package/dist/modules/agent-client/build.mjs.map +1 -1
- package/dist/modules/cli/channel-install.d.mts +3 -1
- package/dist/modules/cli/channel-install.mjs +4 -11
- package/dist/modules/cli/channel-install.mjs.map +2 -2
- package/dist/modules/cli/cli.mjs +15 -5
- package/dist/modules/cli/cli.mjs.map +2 -2
- package/dist/modules/cli/dev.d.mts +2 -2
- package/dist/modules/cli/dev.mjs +22 -36
- package/dist/modules/cli/dev.mjs.map +2 -2
- package/dist/modules/cli/output.mjs +1 -1
- package/dist/modules/cli/output.mjs.map +2 -2
- package/dist/modules/cli/publish.d.mts +1 -0
- package/dist/modules/cli/publish.mjs +3 -0
- package/dist/modules/cli/publish.mjs.map +2 -2
- package/dist/modules/compile.mjs +0 -7
- package/dist/modules/compile.mjs.map +2 -2
- package/dist/modules/public.d.mts +3 -2
- package/dist/modules/public.mjs +12 -4
- package/dist/modules/public.mjs.map +2 -2
- package/examples/release-scout/agent/channels/github.ts +32 -2
- package/package.json +5 -5
package/HOSTING.md
CHANGED
|
@@ -269,6 +269,6 @@ Optional readers preserve source compatibility with existing hosts. Definitions
|
|
|
269
269
|
requesting bindings fail clearly if hosting does not provide them. Installing these
|
|
270
270
|
packages alone does not change Final's deployed service wiring or provision secrets.
|
|
271
271
|
|
|
272
|
-
New compiles emit manifest version 4. Hosts
|
|
273
|
-
|
|
274
|
-
publishing newly compiled agents.
|
|
272
|
+
New compiles emit manifest version 4. Hosts read versions 2 through 4; older
|
|
273
|
+
channel entries default to no credentials and an empty surface. Upgrade hosting
|
|
274
|
+
before publishing newly compiled agents.
|
package/README.md
CHANGED
|
@@ -36,4 +36,8 @@ the same path with the `final` binding. Explicit URL declarations remain static.
|
|
|
36
36
|
See the repository's [hosting guide](HOSTING.md) for provider contexts,
|
|
37
37
|
resource lookup, and the required hosting integration.
|
|
38
38
|
|
|
39
|
-
Local
|
|
39
|
+
Local previews can use explicitly declared secrets from `AGENT_LOCAL_SECRETS_JSON`. Installed app operations and member and chat capabilities require an authenticated host. Embedders may supply the same opaque credential facade to `startDevServer`; raw application credentials are never exposed to authored modules.
|
|
40
|
+
|
|
41
|
+
Authored channel applications use `defineChannel` from `/channels` and compile into the published bundle. Use `bundleRef('channels/support')` in `agent.ts` to configure an existing channel module; its credentials and routes are derived from that module. Credential enums and opaque credential types are available from the same facade.
|
|
42
|
+
|
|
43
|
+
`client.definitions.publish({ definition, ref, activate: false })` publishes an approved immutable source revision without changing the live agent, routes, listeners, or schedules. The CLI equivalent is `publish --no-activate`. Credential declarations still need normal administrator approval. Install an exported channel with `channel install <key> --revision <id> --project <id> --install <id>`; use `--replace` or `channelBindings.create({ ..., replace: true })` to explicitly update an active binding while retaining its ID and binding base URL. Omitted configuration preserves current settings during replacement; an explicit empty configuration resets to source defaults. New source publication never silently updates an installed revision pin.
|
|
@@ -35,10 +35,11 @@ export interface DefinitionsApiIface {
|
|
|
35
35
|
harness?: string;
|
|
36
36
|
}) => Promise<CompileResultIface>;
|
|
37
37
|
commit: (args: DefinitionRefIface & CommitDefinitionRequestIface) => Promise<CommitResultIface>;
|
|
38
|
-
/**
|
|
38
|
+
/** Publishes an immutable revision; activate:false leaves the live agent unchanged. */
|
|
39
39
|
publish: (args: DefinitionRefIface & {
|
|
40
40
|
ref: string;
|
|
41
41
|
note?: string;
|
|
42
|
+
activate?: boolean;
|
|
42
43
|
}) => Promise<PublishResultIface>;
|
|
43
44
|
/** The agent directory's files at `ref` (default branch when omitted). */
|
|
44
45
|
files: (args: DefinitionRefIface & {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/agent-client/build.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n commitDefinitionRequestSchema,\n commitResultSchema,\n compatibilityReportSchema,\n compileDefinitionRequestSchema,\n compileResultSchema,\n computerSetupGuideDetailSchema,\n computerSetupGuideListSchema,\n createDefinitionRequestSchema,\n credentialPolicyPreviewSchema,\n definitionChannelsResponseSchema,\n definitionCloneUrlSchema,\n definitionFilesSchema,\n definitionListSchema,\n definitionSchema,\n previewCredentialPolicyRequestSchema,\n providerListSchema,\n publishComputerSetupGuideRequestSchema,\n publishComputerSetupGuideResultSchema,\n publishDefinitionRequestSchema,\n publishResultSchema,\n revisionDiffSchema,\n revisionListSchema,\n revisionSchema,\n scheduleListSchema,\n scheduleRunResultSchema,\n scheduleSchema,\n updateScheduleRequestSchema,\n type CommitDefinitionRequestIface,\n type CommitResultIface,\n type CompatibilityReportIface,\n type CompileResultIface,\n type ComputerSetupGuideDetailIface,\n type ComputerSetupGuideIface,\n type ComputerSetupGuideVersionIface,\n type CreateDefinitionRequestIface,\n type CredentialPolicyPreviewIface,\n type DefinitionChannelIface,\n type DefinitionCloneUrlIface,\n type DefinitionFilesIface,\n type DefinitionIface,\n type PreviewCredentialPolicyRequestIface,\n type ProviderEntryIface,\n type PublishComputerSetupGuideRequestIface,\n type PublishResultIface,\n type RevisionDiffIface,\n type RevisionIface,\n type ScheduleIface,\n type ScheduleRunResultIface,\n type UpdateScheduleRequestIface,\n} from '@finalai/agent-protocol/agent-platform';\nimport { encodePath, type ClientContextIface, type SignalOptionsIface } from \"./context.mjs\";\nimport { clientError, ClientErrorCode } from \"./errors.mjs\";\nimport { HttpMethod } from \"./http.mjs\";\n\n// Definitions, providers, setup guides, schedules, credentials and budgets:\n// what Build, settings and CI use.\n\nexport interface DefinitionRefIface extends SignalOptionsIface {\n /** Definition id or slug. */\n definition: string;\n}\n\nexport interface DefinitionsApiIface {\n /** Compiles a draft into an immutable test snapshot without publishing or activating schedules/channels. */\n testRevision: (args: DefinitionRefIface & { ref: string }) => Promise<RevisionIface>;\n previewCredentialPolicy: (\n args: DefinitionRefIface & PreviewCredentialPolicyRequestIface,\n ) => Promise<CredentialPolicyPreviewIface>;\n /**\n * With `projectId`, its definitions and those inherited from its ancestors. Without it,\n * everything the caller can access (an API key: its parent project and every project it is\n * granted; a person: every project they can read).\n */\n list: (\n options?: SignalOptionsIface & { cursor?: string; limit?: number; projectId?: string },\n ) => Promise<{ definitions: DefinitionIface[]; nextCursor: string | null }>;\n /**\n * Creates the definition in `projectId` (editors of that project); omitted, the API key's parent\n * project (a signed-in person's: My Work).\n */\n create: (args: CreateDefinitionRequestIface & SignalOptionsIface) => Promise<DefinitionIface>;\n get: (args: DefinitionRefIface) => Promise<DefinitionIface>;\n /** Compiles the directory at `ref` server-side without publishing. */\n compile: (\n args: DefinitionRefIface & { ref: string; harness?: string },\n ) => Promise<CompileResultIface>;\n commit: (args: DefinitionRefIface & CommitDefinitionRequestIface) => Promise<CommitResultIface>;\n /** Compiles `ref`, stores a revision and makes it current. */\n publish: (\n args: DefinitionRefIface & { ref: string; note?: string },\n ) => Promise<PublishResultIface>;\n /** The agent directory's files at `ref` (default branch when omitted). */\n files: (args: DefinitionRefIface & { ref?: string }) => Promise<DefinitionFilesIface>;\n revisions: (\n args: DefinitionRefIface & { cursor?: string },\n ) => Promise<{ revisions: RevisionIface[]; nextCursor: string | null }>;\n /**\n * What changed in the compiled manifest between two revisions (revision ids\n * or numbers); `to` defaults to the current revision.\n */\n revisionDiff: (\n args: DefinitionRefIface & { from: string | number; to?: string | number },\n ) => Promise<RevisionDiffIface>;\n compatibility: (\n args: DefinitionRefIface & { harness: string; ref?: string },\n ) => Promise<CompatibilityReportIface>;\n /** The agent's live channel bindings and their public route URLs. */\n channels: (args: DefinitionRefIface) => Promise<DefinitionChannelIface[]>;\n /**\n * Archives the definition: it leaves listings, its schedules and channel\n * bindings stop, and new sessions are refused. Its repository is kept.\n */\n archive: (args: DefinitionRefIface) => Promise<DefinitionIface>;\n /**\n * A short-lived, read-only git remote for a Final-hosted repository, for\n * `git clone` (editors of the definition's project).\n */\n cloneUrl: (args: DefinitionRefIface) => Promise<DefinitionCloneUrlIface>;\n}\n\nexport interface ProvidersApiIface {\n list: (options?: SignalOptionsIface) => Promise<ProviderEntryIface[]>;\n}\n\nexport interface ComputerSetupGuidesApiIface {\n list: (options?: SignalOptionsIface) => Promise<ComputerSetupGuideIface[]>;\n /** Guide by slug or id, with its versions. */\n get: (ref: string, options?: SignalOptionsIface) => Promise<ComputerSetupGuideDetailIface>;\n /** Publishes a new version (creating the guide on first publish). */\n publish: (\n args: PublishComputerSetupGuideRequestIface & SignalOptionsIface,\n ) => Promise<{ guide: ComputerSetupGuideIface; version: ComputerSetupGuideVersionIface }>;\n}\n\nexport type ScheduleRef = { scheduleId: string } | { agent: string; key: string };\n\nexport interface SchedulesApiIface {\n list: (options?: SignalOptionsIface & { agent?: string }) => Promise<ScheduleIface[]>;\n runNow: (args: ScheduleRef & SignalOptionsIface) => Promise<ScheduleRunResultIface>;\n update: (\n args: { scheduleId: string } & UpdateScheduleRequestIface & SignalOptionsIface,\n ) => Promise<ScheduleIface>;\n}\n\nconst definitionPath = (definition: string, suffix = ''): string =>\n `/v1/definitions/${encodePath(definition)}${suffix}`;\n\nexport const createDefinitionsApi = ({ http }: ClientContextIface): DefinitionsApiIface => ({\n testRevision: ({ definition, signal, ...value }) =>\n http.request({\n method: HttpMethod.Post,\n path: definitionPath(definition, '/test-revision'),\n body: { schema: compileDefinitionRequestSchema, value },\n response: revisionSchema,\n signal,\n }),\n previewCredentialPolicy: ({ definition, signal, ...value }) =>\n http.request({\n method: HttpMethod.Post,\n path: definitionPath(definition, '/credential-policy/preview'),\n body: { schema: previewCredentialPolicyRequestSchema, value },\n response: credentialPolicyPreviewSchema,\n signal,\n }),\n list: (options) =>\n http.request({\n method: HttpMethod.Get,\n path: '/v1/definitions',\n query: { cursor: options?.cursor, limit: options?.limit, projectId: options?.projectId },\n response: definitionListSchema,\n signal: options?.signal,\n }),\n create: ({ signal, ...value }) =>\n http.request({\n method: HttpMethod.Post,\n path: '/v1/definitions',\n body: { schema: createDefinitionRequestSchema, value },\n response: definitionSchema,\n signal,\n }),\n get: ({ definition, signal }) =>\n http.request({\n method: HttpMethod.Get,\n path: definitionPath(definition),\n response: definitionSchema,\n signal,\n }),\n compile: ({ definition, signal, ...value }) =>\n http.request({\n method: HttpMethod.Post,\n path: definitionPath(definition, '/compile'),\n body: { schema: compileDefinitionRequestSchema, value },\n response: compileResultSchema,\n signal,\n }),\n commit: ({ definition, signal, ...value }) =>\n http.request({\n method: HttpMethod.Post,\n path: definitionPath(definition, '/commit'),\n body: { schema: commitDefinitionRequestSchema, value },\n response: commitResultSchema,\n signal,\n }),\n publish: ({ definition, signal, ...value }) =>\n http.request({\n method: HttpMethod.Post,\n path: definitionPath(definition, '/publish'),\n body: { schema: publishDefinitionRequestSchema, value },\n response: publishResultSchema,\n signal,\n }),\n files: ({ definition, ref, signal }) =>\n http.request({\n method: HttpMethod.Get,\n path: definitionPath(definition, '/files'),\n query: { ref },\n response: definitionFilesSchema,\n signal,\n }),\n revisions: ({ definition, cursor, signal }) =>\n http.request({\n method: HttpMethod.Get,\n path: definitionPath(definition, '/revisions'),\n query: { cursor },\n response: revisionListSchema,\n signal,\n }),\n revisionDiff: ({ definition, from, to, signal }) =>\n http.request({\n method: HttpMethod.Get,\n path: definitionPath(definition, '/revisions/diff'),\n query: { from, to },\n response: revisionDiffSchema,\n signal,\n }),\n compatibility: ({ definition, harness, ref, signal }) =>\n http.request({\n method: HttpMethod.Get,\n path: definitionPath(definition, '/compatibility'),\n query: { harness, ref },\n response: compatibilityReportSchema,\n signal,\n }),\n channels: async ({ definition, signal }) =>\n (\n await http.request({\n method: HttpMethod.Get,\n path: definitionPath(definition, '/channels'),\n response: definitionChannelsResponseSchema,\n signal,\n })\n ).channels,\n archive: ({ definition, signal }) =>\n http.request({\n method: HttpMethod.Post,\n path: definitionPath(definition, '/archive'),\n response: definitionSchema,\n signal,\n }),\n cloneUrl: ({ definition, signal }) =>\n http.request({\n method: HttpMethod.Post,\n path: definitionPath(definition, '/clone-url'),\n response: definitionCloneUrlSchema,\n signal,\n }),\n});\n\nexport const createProvidersApi = ({ http }: ClientContextIface): ProvidersApiIface => ({\n list: async (options) =>\n (\n await http.request({\n method: HttpMethod.Get,\n path: '/v1/providers',\n response: providerListSchema,\n signal: options?.signal,\n })\n ).providers,\n});\n\nexport const createComputerSetupGuidesApi = ({\n http,\n}: ClientContextIface): ComputerSetupGuidesApiIface => ({\n list: async (options) =>\n (\n await http.request({\n method: HttpMethod.Get,\n path: '/v1/computer-setup-guides',\n response: computerSetupGuideListSchema,\n signal: options?.signal,\n })\n ).guides,\n get: (ref, options) =>\n http.request({\n method: HttpMethod.Get,\n path: `/v1/computer-setup-guides/${encodePath(ref)}`,\n response: computerSetupGuideDetailSchema,\n signal: options?.signal,\n }),\n publish: ({ signal, ...value }) =>\n http.request({\n method: HttpMethod.Post,\n path: '/v1/computer-setup-guides',\n body: { schema: publishComputerSetupGuideRequestSchema, value },\n response: publishComputerSetupGuideResultSchema,\n signal,\n }),\n});\n\nexport const createSchedulesApi = ({ http }: ClientContextIface): SchedulesApiIface => {\n const list: SchedulesApiIface['list'] = async (options) =>\n (\n await http.request({\n method: HttpMethod.Get,\n path: '/v1/schedules',\n query: { agent: options?.agent },\n response: scheduleListSchema,\n signal: options?.signal,\n })\n ).schedules;\n\n const scheduleIdOf = async (args: ScheduleRef & SignalOptionsIface): Promise<string> => {\n if ('scheduleId' in args) return args.scheduleId;\n const found = (await list({ agent: args.agent, signal: args.signal })).find(\n (schedule) => schedule.key === args.key,\n );\n if (found == null) {\n throw clientError({\n message: `No schedule ${args.key} on agent ${args.agent}`,\n status: 0,\n code: ClientErrorCode.NotFound,\n });\n }\n return found.id;\n };\n\n return {\n list,\n runNow: async (args) =>\n http.request({\n method: HttpMethod.Post,\n path: `/v1/schedules/${encodePath(await scheduleIdOf(args))}/run-now`,\n response: scheduleRunResultSchema,\n signal: args.signal,\n }),\n update: ({ scheduleId, signal, ...value }) =>\n http.request({\n method: HttpMethod.Patch,\n path: `/v1/schedules/${encodePath(scheduleId)}`,\n body: { schema: updateScheduleRequestSchema, value },\n response: scheduleSchema,\n signal,\n }),\n };\n};\n"],
|
|
4
|
+
"sourcesContent": ["import {\n commitDefinitionRequestSchema,\n commitResultSchema,\n compatibilityReportSchema,\n compileDefinitionRequestSchema,\n compileResultSchema,\n computerSetupGuideDetailSchema,\n computerSetupGuideListSchema,\n createDefinitionRequestSchema,\n credentialPolicyPreviewSchema,\n definitionChannelsResponseSchema,\n definitionCloneUrlSchema,\n definitionFilesSchema,\n definitionListSchema,\n definitionSchema,\n previewCredentialPolicyRequestSchema,\n providerListSchema,\n publishComputerSetupGuideRequestSchema,\n publishComputerSetupGuideResultSchema,\n publishDefinitionRequestSchema,\n publishResultSchema,\n revisionDiffSchema,\n revisionListSchema,\n revisionSchema,\n scheduleListSchema,\n scheduleRunResultSchema,\n scheduleSchema,\n updateScheduleRequestSchema,\n type CommitDefinitionRequestIface,\n type CommitResultIface,\n type CompatibilityReportIface,\n type CompileResultIface,\n type ComputerSetupGuideDetailIface,\n type ComputerSetupGuideIface,\n type ComputerSetupGuideVersionIface,\n type CreateDefinitionRequestIface,\n type CredentialPolicyPreviewIface,\n type DefinitionChannelIface,\n type DefinitionCloneUrlIface,\n type DefinitionFilesIface,\n type DefinitionIface,\n type PreviewCredentialPolicyRequestIface,\n type ProviderEntryIface,\n type PublishComputerSetupGuideRequestIface,\n type PublishResultIface,\n type RevisionDiffIface,\n type RevisionIface,\n type ScheduleIface,\n type ScheduleRunResultIface,\n type UpdateScheduleRequestIface,\n} from '@finalai/agent-protocol/agent-platform';\nimport { encodePath, type ClientContextIface, type SignalOptionsIface } from \"./context.mjs\";\nimport { clientError, ClientErrorCode } from \"./errors.mjs\";\nimport { HttpMethod } from \"./http.mjs\";\n\n// Definitions, providers, setup guides, schedules, credentials and budgets:\n// what Build, settings and CI use.\n\nexport interface DefinitionRefIface extends SignalOptionsIface {\n /** Definition id or slug. */\n definition: string;\n}\n\nexport interface DefinitionsApiIface {\n /** Compiles a draft into an immutable test snapshot without publishing or activating schedules/channels. */\n testRevision: (args: DefinitionRefIface & { ref: string }) => Promise<RevisionIface>;\n previewCredentialPolicy: (\n args: DefinitionRefIface & PreviewCredentialPolicyRequestIface,\n ) => Promise<CredentialPolicyPreviewIface>;\n /**\n * With `projectId`, its definitions and those inherited from its ancestors. Without it,\n * everything the caller can access (an API key: its parent project and every project it is\n * granted; a person: every project they can read).\n */\n list: (\n options?: SignalOptionsIface & { cursor?: string; limit?: number; projectId?: string },\n ) => Promise<{ definitions: DefinitionIface[]; nextCursor: string | null }>;\n /**\n * Creates the definition in `projectId` (editors of that project); omitted, the API key's parent\n * project (a signed-in person's: My Work).\n */\n create: (args: CreateDefinitionRequestIface & SignalOptionsIface) => Promise<DefinitionIface>;\n get: (args: DefinitionRefIface) => Promise<DefinitionIface>;\n /** Compiles the directory at `ref` server-side without publishing. */\n compile: (\n args: DefinitionRefIface & { ref: string; harness?: string },\n ) => Promise<CompileResultIface>;\n commit: (args: DefinitionRefIface & CommitDefinitionRequestIface) => Promise<CommitResultIface>;\n /** Publishes an immutable revision; activate:false leaves the live agent unchanged. */\n publish: (\n args: DefinitionRefIface & { ref: string; note?: string; activate?: boolean },\n ) => Promise<PublishResultIface>;\n /** The agent directory's files at `ref` (default branch when omitted). */\n files: (args: DefinitionRefIface & { ref?: string }) => Promise<DefinitionFilesIface>;\n revisions: (\n args: DefinitionRefIface & { cursor?: string },\n ) => Promise<{ revisions: RevisionIface[]; nextCursor: string | null }>;\n /**\n * What changed in the compiled manifest between two revisions (revision ids\n * or numbers); `to` defaults to the current revision.\n */\n revisionDiff: (\n args: DefinitionRefIface & { from: string | number; to?: string | number },\n ) => Promise<RevisionDiffIface>;\n compatibility: (\n args: DefinitionRefIface & { harness: string; ref?: string },\n ) => Promise<CompatibilityReportIface>;\n /** The agent's live channel bindings and their public route URLs. */\n channels: (args: DefinitionRefIface) => Promise<DefinitionChannelIface[]>;\n /**\n * Archives the definition: it leaves listings, its schedules and channel\n * bindings stop, and new sessions are refused. Its repository is kept.\n */\n archive: (args: DefinitionRefIface) => Promise<DefinitionIface>;\n /**\n * A short-lived, read-only git remote for a Final-hosted repository, for\n * `git clone` (editors of the definition's project).\n */\n cloneUrl: (args: DefinitionRefIface) => Promise<DefinitionCloneUrlIface>;\n}\n\nexport interface ProvidersApiIface {\n list: (options?: SignalOptionsIface) => Promise<ProviderEntryIface[]>;\n}\n\nexport interface ComputerSetupGuidesApiIface {\n list: (options?: SignalOptionsIface) => Promise<ComputerSetupGuideIface[]>;\n /** Guide by slug or id, with its versions. */\n get: (ref: string, options?: SignalOptionsIface) => Promise<ComputerSetupGuideDetailIface>;\n /** Publishes a new version (creating the guide on first publish). */\n publish: (\n args: PublishComputerSetupGuideRequestIface & SignalOptionsIface,\n ) => Promise<{ guide: ComputerSetupGuideIface; version: ComputerSetupGuideVersionIface }>;\n}\n\nexport type ScheduleRef = { scheduleId: string } | { agent: string; key: string };\n\nexport interface SchedulesApiIface {\n list: (options?: SignalOptionsIface & { agent?: string }) => Promise<ScheduleIface[]>;\n runNow: (args: ScheduleRef & SignalOptionsIface) => Promise<ScheduleRunResultIface>;\n update: (\n args: { scheduleId: string } & UpdateScheduleRequestIface & SignalOptionsIface,\n ) => Promise<ScheduleIface>;\n}\n\nconst definitionPath = (definition: string, suffix = ''): string =>\n `/v1/definitions/${encodePath(definition)}${suffix}`;\n\nexport const createDefinitionsApi = ({ http }: ClientContextIface): DefinitionsApiIface => ({\n testRevision: ({ definition, signal, ...value }) =>\n http.request({\n method: HttpMethod.Post,\n path: definitionPath(definition, '/test-revision'),\n body: { schema: compileDefinitionRequestSchema, value },\n response: revisionSchema,\n signal,\n }),\n previewCredentialPolicy: ({ definition, signal, ...value }) =>\n http.request({\n method: HttpMethod.Post,\n path: definitionPath(definition, '/credential-policy/preview'),\n body: { schema: previewCredentialPolicyRequestSchema, value },\n response: credentialPolicyPreviewSchema,\n signal,\n }),\n list: (options) =>\n http.request({\n method: HttpMethod.Get,\n path: '/v1/definitions',\n query: { cursor: options?.cursor, limit: options?.limit, projectId: options?.projectId },\n response: definitionListSchema,\n signal: options?.signal,\n }),\n create: ({ signal, ...value }) =>\n http.request({\n method: HttpMethod.Post,\n path: '/v1/definitions',\n body: { schema: createDefinitionRequestSchema, value },\n response: definitionSchema,\n signal,\n }),\n get: ({ definition, signal }) =>\n http.request({\n method: HttpMethod.Get,\n path: definitionPath(definition),\n response: definitionSchema,\n signal,\n }),\n compile: ({ definition, signal, ...value }) =>\n http.request({\n method: HttpMethod.Post,\n path: definitionPath(definition, '/compile'),\n body: { schema: compileDefinitionRequestSchema, value },\n response: compileResultSchema,\n signal,\n }),\n commit: ({ definition, signal, ...value }) =>\n http.request({\n method: HttpMethod.Post,\n path: definitionPath(definition, '/commit'),\n body: { schema: commitDefinitionRequestSchema, value },\n response: commitResultSchema,\n signal,\n }),\n publish: ({ definition, signal, ...value }) =>\n http.request({\n method: HttpMethod.Post,\n path: definitionPath(definition, '/publish'),\n body: { schema: publishDefinitionRequestSchema, value },\n response: publishResultSchema,\n signal,\n }),\n files: ({ definition, ref, signal }) =>\n http.request({\n method: HttpMethod.Get,\n path: definitionPath(definition, '/files'),\n query: { ref },\n response: definitionFilesSchema,\n signal,\n }),\n revisions: ({ definition, cursor, signal }) =>\n http.request({\n method: HttpMethod.Get,\n path: definitionPath(definition, '/revisions'),\n query: { cursor },\n response: revisionListSchema,\n signal,\n }),\n revisionDiff: ({ definition, from, to, signal }) =>\n http.request({\n method: HttpMethod.Get,\n path: definitionPath(definition, '/revisions/diff'),\n query: { from, to },\n response: revisionDiffSchema,\n signal,\n }),\n compatibility: ({ definition, harness, ref, signal }) =>\n http.request({\n method: HttpMethod.Get,\n path: definitionPath(definition, '/compatibility'),\n query: { harness, ref },\n response: compatibilityReportSchema,\n signal,\n }),\n channels: async ({ definition, signal }) =>\n (\n await http.request({\n method: HttpMethod.Get,\n path: definitionPath(definition, '/channels'),\n response: definitionChannelsResponseSchema,\n signal,\n })\n ).channels,\n archive: ({ definition, signal }) =>\n http.request({\n method: HttpMethod.Post,\n path: definitionPath(definition, '/archive'),\n response: definitionSchema,\n signal,\n }),\n cloneUrl: ({ definition, signal }) =>\n http.request({\n method: HttpMethod.Post,\n path: definitionPath(definition, '/clone-url'),\n response: definitionCloneUrlSchema,\n signal,\n }),\n});\n\nexport const createProvidersApi = ({ http }: ClientContextIface): ProvidersApiIface => ({\n list: async (options) =>\n (\n await http.request({\n method: HttpMethod.Get,\n path: '/v1/providers',\n response: providerListSchema,\n signal: options?.signal,\n })\n ).providers,\n});\n\nexport const createComputerSetupGuidesApi = ({\n http,\n}: ClientContextIface): ComputerSetupGuidesApiIface => ({\n list: async (options) =>\n (\n await http.request({\n method: HttpMethod.Get,\n path: '/v1/computer-setup-guides',\n response: computerSetupGuideListSchema,\n signal: options?.signal,\n })\n ).guides,\n get: (ref, options) =>\n http.request({\n method: HttpMethod.Get,\n path: `/v1/computer-setup-guides/${encodePath(ref)}`,\n response: computerSetupGuideDetailSchema,\n signal: options?.signal,\n }),\n publish: ({ signal, ...value }) =>\n http.request({\n method: HttpMethod.Post,\n path: '/v1/computer-setup-guides',\n body: { schema: publishComputerSetupGuideRequestSchema, value },\n response: publishComputerSetupGuideResultSchema,\n signal,\n }),\n});\n\nexport const createSchedulesApi = ({ http }: ClientContextIface): SchedulesApiIface => {\n const list: SchedulesApiIface['list'] = async (options) =>\n (\n await http.request({\n method: HttpMethod.Get,\n path: '/v1/schedules',\n query: { agent: options?.agent },\n response: scheduleListSchema,\n signal: options?.signal,\n })\n ).schedules;\n\n const scheduleIdOf = async (args: ScheduleRef & SignalOptionsIface): Promise<string> => {\n if ('scheduleId' in args) return args.scheduleId;\n const found = (await list({ agent: args.agent, signal: args.signal })).find(\n (schedule) => schedule.key === args.key,\n );\n if (found == null) {\n throw clientError({\n message: `No schedule ${args.key} on agent ${args.agent}`,\n status: 0,\n code: ClientErrorCode.NotFound,\n });\n }\n return found.id;\n };\n\n return {\n list,\n runNow: async (args) =>\n http.request({\n method: HttpMethod.Post,\n path: `/v1/schedules/${encodePath(await scheduleIdOf(args))}/run-now`,\n response: scheduleRunResultSchema,\n signal: args.signal,\n }),\n update: ({ scheduleId, signal, ...value }) =>\n http.request({\n method: HttpMethod.Patch,\n path: `/v1/schedules/${encodePath(scheduleId)}`,\n body: { schema: updateScheduleRequestSchema, value },\n response: scheduleSchema,\n signal,\n }),\n };\n};\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { AgentClientIface } from "../agent-client/client.mjs";
|
|
2
2
|
import { type OutputIface } from "./output.mjs";
|
|
3
3
|
export interface ChannelInstallArgsIface {
|
|
4
|
-
|
|
4
|
+
channelKey: string;
|
|
5
|
+
revisionId: string;
|
|
5
6
|
projectId: string;
|
|
7
|
+
replace?: boolean;
|
|
6
8
|
connectorInstallId: string;
|
|
7
9
|
client: AgentClientIface;
|
|
8
10
|
output: OutputIface;
|
|
@@ -1,21 +1,14 @@
|
|
|
1
1
|
import { errorLines } from "./output.mjs";
|
|
2
|
-
const names = ["slack", "discord", "github", "linear"];
|
|
3
2
|
const runChannelInstall = async (args) => {
|
|
4
|
-
const name = names.find(
|
|
5
|
-
(candidate) => args.packageName === `@finalai/${candidate}-channel` || args.packageName === `@finalai/final-agent-provider/channels/${candidate}`
|
|
6
|
-
);
|
|
7
|
-
if (name == null) {
|
|
8
|
-
args.output.stderr(`error: unsupported shared channel ${args.packageName}`);
|
|
9
|
-
return 2;
|
|
10
|
-
}
|
|
11
3
|
try {
|
|
12
4
|
const result = await args.client.channelBindings.create({
|
|
13
5
|
projectId: args.projectId,
|
|
14
6
|
connectorInstallId: args.connectorInstallId,
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
revisionId: args.revisionId,
|
|
8
|
+
channelKey: args.channelKey,
|
|
9
|
+
...args.replace == null ? {} : { replace: args.replace }
|
|
17
10
|
});
|
|
18
|
-
args.output.stdout(`installed ${
|
|
11
|
+
args.output.stdout(`installed ${args.channelKey}: ${result.bindingId}`);
|
|
19
12
|
for (const route of result.routes) {
|
|
20
13
|
const url = route.url ?? route.aliasUrl;
|
|
21
14
|
if (url != null) args.output.stdout(` ${route.method} ${url}`);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/cli/channel-install.ts"],
|
|
4
|
-
"sourcesContent": ["import type { AgentClientIface } from \"../agent-client/client.mjs\";\nimport { errorLines, type OutputIface } from \"./output.mjs\";\
|
|
5
|
-
"mappings": "AACA,SAAS,kBAAoC;
|
|
4
|
+
"sourcesContent": ["import type { AgentClientIface } from \"../agent-client/client.mjs\";\nimport { errorLines, type OutputIface } from \"./output.mjs\";\nexport interface ChannelInstallArgsIface {\n channelKey: string;\n revisionId: string;\n projectId: string;\n replace?: boolean;\n connectorInstallId: string;\n client: AgentClientIface;\n output: OutputIface;\n}\nexport const runChannelInstall = async (args: ChannelInstallArgsIface): Promise<number> => {\n try {\n const result = await args.client.channelBindings.create({\n projectId: args.projectId,\n connectorInstallId: args.connectorInstallId,\n revisionId: args.revisionId,\n channelKey: args.channelKey,\n ...(args.replace == null ? {} : { replace: args.replace }),\n });\n args.output.stdout(`installed ${args.channelKey}: ${result.bindingId}`);\n for (const route of result.routes) {\n const url = route.url ?? route.aliasUrl;\n if (url != null) args.output.stdout(` ${route.method} ${url}`);\n }\n return 0;\n } catch (error) {\n for (const line of errorLines(error)) args.output.stderr(line);\n return 1;\n }\n};\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,kBAAoC;AAUtC,MAAM,oBAAoB,OAAO,SAAmD;AACzF,MAAI;AACF,UAAM,SAAS,MAAM,KAAK,OAAO,gBAAgB,OAAO;AAAA,MACtD,WAAW,KAAK;AAAA,MAChB,oBAAoB,KAAK;AAAA,MACzB,YAAY,KAAK;AAAA,MACjB,YAAY,KAAK;AAAA,MACjB,GAAI,KAAK,WAAW,OAAO,CAAC,IAAI,EAAE,SAAS,KAAK,QAAQ;AAAA,IAC1D,CAAC;AACD,SAAK,OAAO,OAAO,aAAa,KAAK,UAAU,KAAK,OAAO,SAAS,EAAE;AACtE,eAAW,SAAS,OAAO,QAAQ;AACjC,YAAM,MAAM,MAAM,OAAO,MAAM;AAC/B,UAAI,OAAO,KAAM,MAAK,OAAO,OAAO,KAAK,MAAM,MAAM,IAAI,GAAG,EAAE;AAAA,IAChE;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,eAAW,QAAQ,WAAW,KAAK,EAAG,MAAK,OAAO,OAAO,IAAI;AAC7D,WAAO;AAAA,EACT;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/modules/cli/cli.mjs
CHANGED
|
@@ -17,7 +17,7 @@ const USAGE = [
|
|
|
17
17
|
" build [dir] compile the agent directory and report on its harness",
|
|
18
18
|
" dev [dir] serve its channel routes at http://localhost:<port>/<channel><path>",
|
|
19
19
|
" publish [dir] --agent <slug> commit the checkout to the agent and publish it",
|
|
20
|
-
" channel install <
|
|
20
|
+
" channel install <key> --revision <id> --project <id> --install <id> [--replace] install or explicitly update a published channel",
|
|
21
21
|
" conformance <module> run the harness conformance kit against a harness the module exports",
|
|
22
22
|
"",
|
|
23
23
|
"options:",
|
|
@@ -26,6 +26,8 @@ const USAGE = [
|
|
|
26
26
|
" --ref <ref> publish: the ref to publish (GitHub-backed agents)",
|
|
27
27
|
" --message <text> publish: commit message",
|
|
28
28
|
" --note <text> publish: revision note",
|
|
29
|
+
" --no-activate publish: store approved source without changing the live agent",
|
|
30
|
+
" --replace channel install: explicitly update the existing binding",
|
|
29
31
|
` --port <port> dev: port to listen on (default ${DEFAULT_DEV_PORT})`,
|
|
30
32
|
' --export <name> conformance: the export to test (default "default"): a HarnessIface or { harness, dial }',
|
|
31
33
|
" --profile <name> conformance: final (default) or plain-acp-v2",
|
|
@@ -46,9 +48,12 @@ const optionsConfig = {
|
|
|
46
48
|
ref: { type: "string" },
|
|
47
49
|
message: { type: "string" },
|
|
48
50
|
note: { type: "string" },
|
|
51
|
+
"no-activate": { type: "boolean" },
|
|
49
52
|
port: { type: "string" },
|
|
50
53
|
project: { type: "string" },
|
|
51
54
|
install: { type: "string" },
|
|
55
|
+
replace: { type: "boolean" },
|
|
56
|
+
revision: { type: "string" },
|
|
52
57
|
export: { type: "string" },
|
|
53
58
|
profile: { type: "string" },
|
|
54
59
|
timeout: { type: "string" },
|
|
@@ -96,9 +101,11 @@ const runAgentsCommand = async (deps) => {
|
|
|
96
101
|
fetch: deps.fetch
|
|
97
102
|
});
|
|
98
103
|
if (command === "channel") {
|
|
99
|
-
const
|
|
100
|
-
if (dirArg !== "install" ||
|
|
101
|
-
output.stderr(
|
|
104
|
+
const channelKey = extra[0];
|
|
105
|
+
if (dirArg !== "install" || channelKey == null || values.revision == null || values.project == null || values.install == null) {
|
|
106
|
+
output.stderr(
|
|
107
|
+
"error: channel install needs <key> --revision <id> --project <id> --install <id>"
|
|
108
|
+
);
|
|
102
109
|
return 2;
|
|
103
110
|
}
|
|
104
111
|
if (apiKey == null) {
|
|
@@ -106,7 +113,9 @@ const runAgentsCommand = async (deps) => {
|
|
|
106
113
|
return 2;
|
|
107
114
|
}
|
|
108
115
|
return runChannelInstall({
|
|
109
|
-
|
|
116
|
+
channelKey,
|
|
117
|
+
revisionId: values.revision,
|
|
118
|
+
replace: values.replace,
|
|
110
119
|
projectId: values.project,
|
|
111
120
|
connectorInstallId: values.install,
|
|
112
121
|
client: client(apiKey),
|
|
@@ -145,6 +154,7 @@ const runAgentsCommand = async (deps) => {
|
|
|
145
154
|
ref: values.ref ?? null,
|
|
146
155
|
message: values.message ?? DEFAULT_COMMIT_MESSAGE,
|
|
147
156
|
note: values.note ?? null,
|
|
157
|
+
activate: values["no-activate"] === true ? false : void 0,
|
|
148
158
|
client: client(apiKey),
|
|
149
159
|
listFiles: deps.listFiles ?? gitListFiles,
|
|
150
160
|
output
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/cli/cli.ts"],
|
|
4
|
-
"sourcesContent": ["import { resolve } from 'node:path';\nimport { parseArgs } from 'node:util';\nimport * as z from 'zod';\nimport { createClient, type AgentClientIface } from \"../agent-client/client.mjs\";\nimport type { FetchIface } from \"../agent-client/http.mjs\";\nimport { runChannelInstall } from \"./channel-install.mjs\";\nimport { runBuild } from \"./build.mjs\";\nimport { runConformance, type ImportModule } from \"./conformance.mjs\";\nimport { DEFAULT_DEV_PORT, runDev } from \"./dev.mjs\";\nimport { gitListFiles, type ListFiles } from \"./files.mjs\";\nimport type { OutputIface } from \"./output.mjs\";\nimport { runPublish } from \"./publish.mjs\";\n\n// Agent CLI commands:\n// `build` and `publish`, plus `dev` and `conformance`. Shipped as the `final-agents` bin until a general\n// `final` CLI exists; `runAgentsCommand` is what `final agents` would mount.\n\n// The agents API, authenticated with FINAL_API_KEY.\nexport const DEFAULT_AGENTS_HOST = 'https://agent-session.final.ai/api';\n\nconst DEFAULT_COMMIT_MESSAGE = 'Publish with final agents publish';\n\nconst USAGE = [\n 'usage: final-agents <command> [options]',\n '',\n 'commands:',\n ' build [dir] compile the agent directory and report on its harness',\n ' dev [dir] serve its channel routes at http://localhost:<port>/<channel><path>',\n ' publish [dir] --agent <slug> commit the checkout to the agent and publish it',\n ' channel install <
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { resolve } from 'node:path';\nimport { parseArgs } from 'node:util';\nimport * as z from 'zod';\nimport { createClient, type AgentClientIface } from \"../agent-client/client.mjs\";\nimport type { FetchIface } from \"../agent-client/http.mjs\";\nimport { runChannelInstall } from \"./channel-install.mjs\";\nimport { runBuild } from \"./build.mjs\";\nimport { runConformance, type ImportModule } from \"./conformance.mjs\";\nimport { DEFAULT_DEV_PORT, runDev } from \"./dev.mjs\";\nimport { gitListFiles, type ListFiles } from \"./files.mjs\";\nimport type { OutputIface } from \"./output.mjs\";\nimport { runPublish } from \"./publish.mjs\";\n\n// Agent CLI commands:\n// `build` and `publish`, plus `dev` and `conformance`. Shipped as the `final-agents` bin until a general\n// `final` CLI exists; `runAgentsCommand` is what `final agents` would mount.\n\n// The agents API, authenticated with FINAL_API_KEY.\nexport const DEFAULT_AGENTS_HOST = 'https://agent-session.final.ai/api';\n\nconst DEFAULT_COMMIT_MESSAGE = 'Publish with final agents publish';\n\nconst USAGE = [\n 'usage: final-agents <command> [options]',\n '',\n 'commands:',\n ' build [dir] compile the agent directory and report on its harness',\n ' dev [dir] serve its channel routes at http://localhost:<port>/<channel><path>',\n ' publish [dir] --agent <slug> commit the checkout to the agent and publish it',\n ' channel install <key> --revision <id> --project <id> --install <id> [--replace] install or explicitly update a published channel',\n ' conformance <module> run the harness conformance kit against a harness the module exports',\n '',\n 'options:',\n ' --host <url> agent platform API (overrides FINAL_API_HOST; default ' +\n DEFAULT_AGENTS_HOST +\n ')',\n ' --agent <slug> publish: the agent definition (slug or id)',\n ' --ref <ref> publish: the ref to publish (GitHub-backed agents)',\n ' --message <text> publish: commit message',\n ' --note <text> publish: revision note',\n ' --no-activate publish: store approved source without changing the live agent',\n ' --replace channel install: explicitly update the existing binding',\n ` --port <port> dev: port to listen on (default ${DEFAULT_DEV_PORT})`,\n ' --export <name> conformance: the export to test (default \"default\"): a HarnessIface or { harness, dial }',\n ' --profile <name> conformance: final (default) or plain-acp-v2',\n ' --timeout <ms> conformance: per-case timeout',\n ' --json conformance: print the report as JSON',\n '',\n 'FINAL_API_KEY authenticates. build checks compatibility only with it.',\n 'FINAL_API_HOST selects the deployment for build and publish; it does not rewrite authored URLs.',\n 'dev reads route secrets from AGENT_LOCAL_SECRETS_JSON ({\"name\": \"value\"}), limited to the manifest\\'s secrets.',\n].join('\\n');\n\nconst envSchema = z.object({\n FINAL_API_KEY: z.string().min(1).optional(),\n FINAL_API_HOST: z.string().url().optional(),\n});\n\nexport interface AgentsCliDepsIface {\n argv: string[];\n env: Record<string, string | undefined>;\n cwd: string;\n output: OutputIface;\n // Seams: API requests and the checkout's file listing.\n fetch?: FetchIface;\n listFiles?: ListFiles;\n // Ends long-running commands (dev); main.ts aborts it on SIGINT and SIGTERM.\n signal?: AbortSignal;\n // Seam: loads the conformance module (dynamic import by file URL).\n importModule?: ImportModule;\n}\n\nconst optionsConfig = {\n host: { type: 'string' },\n agent: { type: 'string' },\n ref: { type: 'string' },\n message: { type: 'string' },\n note: { type: 'string' },\n 'no-activate': { type: 'boolean' },\n port: { type: 'string' },\n project: { type: 'string' },\n install: { type: 'string' },\n replace: { type: 'boolean' },\n revision: { type: 'string' },\n export: { type: 'string' },\n profile: { type: 'string' },\n timeout: { type: 'string' },\n json: { type: 'boolean' },\n help: { type: 'boolean', short: 'h' },\n} as const;\n\nconst parseCommandLine = (argv: string[]) =>\n parseArgs({ args: argv, options: optionsConfig, allowPositionals: true });\n\ntype ParsedResult =\n | { ok: true; parsed: ReturnType<typeof parseCommandLine> }\n | { ok: false; message: string };\n\nconst parse = (argv: string[]): ParsedResult => {\n try {\n return { ok: true, parsed: parseCommandLine(argv) };\n } catch (cause) {\n return { ok: false, message: cause instanceof Error ? cause.message : String(cause) };\n }\n};\n\nexport const runAgentsCommand = async (deps: AgentsCliDepsIface): Promise<number> => {\n const { output } = deps;\n const parsedArgs = parse(deps.argv);\n if (!parsedArgs.ok) {\n output.stderr(`error: ${parsedArgs.message}`);\n output.stderr(USAGE);\n return 2;\n }\n const { values, positionals } = parsedArgs.parsed;\n const [command, dirArg, ...extra] = positionals;\n if (values.help === true || command == null || command === 'help') {\n (command == null && values.help !== true ? output.stderr : output.stdout)(USAGE);\n return command == null && values.help !== true ? 2 : 0;\n }\n if (extra.length > 0 && !(command === 'channel' && dirArg === 'install' && extra.length === 1)) {\n output.stderr(`error: unexpected arguments: ${extra.join(' ')}`);\n return 2;\n }\n const env = envSchema.safeParse(deps.env);\n if (!env.success) {\n output.stderr(\n 'error: FINAL_API_KEY must be nonempty and FINAL_API_HOST must be an absolute URL',\n );\n return 2;\n }\n const apiKey = env.success ? (env.data.FINAL_API_KEY ?? null) : null;\n const dir = resolve(deps.cwd, dirArg ?? '.');\n const client = (key: string): AgentClientIface =>\n createClient({\n host: values.host ?? env.data.FINAL_API_HOST ?? DEFAULT_AGENTS_HOST,\n auth: { apiKey: key },\n fetch: deps.fetch,\n });\n\n if (command === 'channel') {\n const channelKey = extra[0];\n if (\n dirArg !== 'install' ||\n channelKey == null ||\n values.revision == null ||\n values.project == null ||\n values.install == null\n ) {\n output.stderr(\n 'error: channel install needs <key> --revision <id> --project <id> --install <id>',\n );\n return 2;\n }\n if (apiKey == null) {\n output.stderr('error: set FINAL_API_KEY to a Final API key');\n return 2;\n }\n return runChannelInstall({\n channelKey,\n revisionId: values.revision,\n replace: values.replace,\n projectId: values.project,\n connectorInstallId: values.install,\n client: client(apiKey),\n output,\n });\n }\n if (command === 'build') {\n return runBuild({ dir, client: apiKey == null ? null : client(apiKey), output });\n }\n if (command === 'dev') {\n const port = values.port == null ? DEFAULT_DEV_PORT : Number(values.port);\n if (!Number.isInteger(port) || port < 0 || port > 65_535) {\n output.stderr(`error: --port must be a port number`);\n return 2;\n }\n return runDev({\n dir,\n port,\n env: deps.env,\n output,\n signal: deps.signal ?? new AbortController().signal,\n });\n }\n if (command === 'publish') {\n if (values.agent == null) {\n output.stderr('error: publish needs --agent <slug>');\n return 2;\n }\n if (apiKey == null) {\n output.stderr('error: set FINAL_API_KEY to a Final API key');\n return 2;\n }\n return runPublish({\n dir,\n agent: values.agent,\n ref: values.ref ?? null,\n message: values.message ?? DEFAULT_COMMIT_MESSAGE,\n note: values.note ?? null,\n activate: values['no-activate'] === true ? false : undefined,\n client: client(apiKey),\n listFiles: deps.listFiles ?? gitListFiles,\n output,\n });\n }\n if (command === 'conformance') {\n if (dirArg == null) {\n output.stderr('error: conformance needs <module>');\n return 2;\n }\n const timeoutMs = values.timeout == null ? null : Number(values.timeout);\n if (timeoutMs != null && (!Number.isInteger(timeoutMs) || timeoutMs <= 0)) {\n output.stderr('error: --timeout must be a positive number of milliseconds');\n return 2;\n }\n return runConformance({\n module: dirArg,\n exportName: values.export ?? 'default',\n profile: values.profile ?? 'final',\n timeoutMs,\n json: values.json === true,\n cwd: deps.cwd,\n output,\n importModule: deps.importModule,\n signal: deps.signal,\n });\n }\n output.stderr(`error: unknown command ${command}`);\n output.stderr(USAGE);\n return 2;\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type ChannelCredentialsIface } from '@finalai/agent-provider';
|
|
2
2
|
import { type OutputIface } from "./output.mjs";
|
|
3
3
|
export declare const DEFAULT_DEV_PORT = 3000;
|
|
4
4
|
export declare const parseLocalSecrets: (text: string | undefined) => Record<string, string> | null;
|
|
@@ -7,7 +7,7 @@ export interface DevServerArgsIface {
|
|
|
7
7
|
port: number;
|
|
8
8
|
hostname?: string;
|
|
9
9
|
secrets: Record<string, string>;
|
|
10
|
-
|
|
10
|
+
credentials?: Record<string, ChannelCredentialsIface>;
|
|
11
11
|
output: OutputIface;
|
|
12
12
|
fetch?: typeof fetch;
|
|
13
13
|
}
|
package/dist/modules/cli/dev.mjs
CHANGED
|
@@ -127,11 +127,14 @@ const startDevServer = async (args) => {
|
|
|
127
127
|
}
|
|
128
128
|
const allowed = new Set(current.manifest.secrets);
|
|
129
129
|
const stem = target.stem;
|
|
130
|
-
const
|
|
130
|
+
const selected = current.manifest.channels.find((binding) => binding.key === stem);
|
|
131
|
+
const appName = selected?.credentials.app;
|
|
132
|
+
const declared = new Set(selected?.credentials.secrets ?? []);
|
|
131
133
|
const response = await current.bundle.runtime.handleChannelRoute({
|
|
132
134
|
export: exportName,
|
|
133
135
|
context: createLocalChannelContext({
|
|
134
|
-
|
|
136
|
+
url: `${origin}/${stem}`,
|
|
137
|
+
credentials: appName == null || args.credentials == null || !Object.hasOwn(args.credentials, appName) ? void 0 : args.credentials[appName],
|
|
135
138
|
secret: async (name) => {
|
|
136
139
|
if (!allowed.has(name)) {
|
|
137
140
|
output.stderr(
|
|
@@ -139,20 +142,17 @@ const startDevServer = async (args) => {
|
|
|
139
142
|
);
|
|
140
143
|
return null;
|
|
141
144
|
}
|
|
145
|
+
if (!declared.has(name)) {
|
|
146
|
+
output.stderr(
|
|
147
|
+
`credentials.secret(${JSON.stringify(name)}): not in this channel's declared secrets`
|
|
148
|
+
);
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
142
151
|
return args.secrets[name] ?? null;
|
|
143
152
|
}
|
|
144
153
|
}),
|
|
145
154
|
request: await toRequest(request, origin),
|
|
146
155
|
path: target.path,
|
|
147
|
-
secrets: {
|
|
148
|
-
get: async (name) => {
|
|
149
|
-
if (!allowed.has(name)) {
|
|
150
|
-
output.stderr(`secrets.get(${JSON.stringify(name)}): not in the manifest's secrets`);
|
|
151
|
-
return null;
|
|
152
|
-
}
|
|
153
|
-
return args.secrets[name] ?? null;
|
|
154
|
-
}
|
|
155
|
-
},
|
|
156
156
|
receive: async (input) => {
|
|
157
157
|
output.stdout(`receive (${stem}): ${previewInput(input)}`);
|
|
158
158
|
return { conversationId: "local" };
|
|
@@ -184,16 +184,15 @@ const startDevServer = async (args) => {
|
|
|
184
184
|
response: new Response("No custom channel socket route", { status: 404 })
|
|
185
185
|
};
|
|
186
186
|
const bundle = current.bundle;
|
|
187
|
-
const
|
|
187
|
+
const selected = current.manifest.channels.find((binding) => binding.key === target.stem);
|
|
188
|
+
const appName = selected?.credentials.app;
|
|
189
|
+
const declared = new Set(selected?.credentials.secrets ?? []);
|
|
188
190
|
const allowed = new Set(current.manifest.secrets);
|
|
189
191
|
const request = new Request(await toRequest(incoming, origin), { signal });
|
|
190
192
|
return openChannelSocket({
|
|
191
193
|
signal,
|
|
192
194
|
context: {
|
|
193
195
|
request,
|
|
194
|
-
secrets: {
|
|
195
|
-
get: async (name) => allowed.has(name) ? args.secrets[name] ?? null : null
|
|
196
|
-
},
|
|
197
196
|
receive: async (input) => {
|
|
198
197
|
output.stdout(`receive (${target.stem}): ${previewInput(input)}`);
|
|
199
198
|
return { conversationId: "local" };
|
|
@@ -203,7 +202,8 @@ const startDevServer = async (args) => {
|
|
|
203
202
|
const response = await bundle.runtime.handleChannelSocket({
|
|
204
203
|
export: exportName,
|
|
205
204
|
context: createLocalChannelContext({
|
|
206
|
-
|
|
205
|
+
url: `${origin}/${target.stem}`,
|
|
206
|
+
credentials: appName == null || args.credentials == null || !Object.hasOwn(args.credentials, appName) ? void 0 : args.credentials[appName],
|
|
207
207
|
secret: async (name) => {
|
|
208
208
|
if (!allowed.has(name)) {
|
|
209
209
|
output.stderr(
|
|
@@ -211,6 +211,12 @@ const startDevServer = async (args) => {
|
|
|
211
211
|
);
|
|
212
212
|
return null;
|
|
213
213
|
}
|
|
214
|
+
if (!declared.has(name)) {
|
|
215
|
+
output.stderr(
|
|
216
|
+
`credentials.secret(${JSON.stringify(name)}): not in this channel's declared secrets`
|
|
217
|
+
);
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
214
220
|
return args.secrets[name] ?? null;
|
|
215
221
|
}
|
|
216
222
|
}),
|
|
@@ -259,32 +265,12 @@ const runDev = async (args) => {
|
|
|
259
265
|
args.output.stderr("error: AGENT_LOCAL_SECRETS_JSON must be a JSON object of name \u2192 value");
|
|
260
266
|
return 2;
|
|
261
267
|
}
|
|
262
|
-
let apps = {};
|
|
263
|
-
const metadata = args.env["AGENT_LOCAL_APP_INFO_JSON"];
|
|
264
|
-
if (metadata != null) {
|
|
265
|
-
try {
|
|
266
|
-
apps = z.record(
|
|
267
|
-
z.string().min(1),
|
|
268
|
-
z.object({
|
|
269
|
-
clientId: z.string(),
|
|
270
|
-
clientSecret: z.string(),
|
|
271
|
-
signingSecret: z.string().optional()
|
|
272
|
-
})
|
|
273
|
-
).parse(JSON.parse(metadata));
|
|
274
|
-
} catch {
|
|
275
|
-
args.output.stderr(
|
|
276
|
-
"error: AGENT_LOCAL_APP_INFO_JSON must map app names to OAuth/signing metadata"
|
|
277
|
-
);
|
|
278
|
-
return 2;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
268
|
let server;
|
|
282
269
|
try {
|
|
283
270
|
server = await startDevServer({
|
|
284
271
|
dir: args.dir,
|
|
285
272
|
port: args.port,
|
|
286
273
|
secrets,
|
|
287
|
-
apps,
|
|
288
274
|
output: args.output
|
|
289
275
|
});
|
|
290
276
|
} catch (cause) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/cli/dev.ts"],
|
|
4
|
-
"sourcesContent": ["import { createLocalChannelContext } from '@finalai/agent-provider/local-channel-context';\nimport {\n DiagnosticSeverity,\n hasErrors,\n loadBundleInLocalIsolate,\n type LoadedBundleIface,\n} from '@finalai/agent-definition/compiler';\nimport {\n ProviderRefKind,\n type AgentManifestIface,\n type JsonValue,\n type InstalledAppInfoIface,\n} from '@finalai/agent-provider';\nimport { openChannelSocket } from '@finalai/agent-provider/local-channel-socket';\nimport { watch, type FSWatcher } from 'node:fs';\nimport { createServer, type IncomingMessage, type ServerResponse } from 'node:http';\nimport * as z from 'zod';\nimport { compile } from \"../compile.mjs\";\nimport { attachDevChannelSockets } from \"./channel-socket.mjs\";\nimport { diagnosticLine, type OutputIface } from \"./output.mjs\";\n\n// Local HTTP and WebSocket previews serve declared channel routes.\n// Routes run in a local stand-in for the Worker isolate (a realm with Worker\n// globals only). There is no platform behind it: `receive` prints what the\n// route would deliver, and `secrets.get` reads AGENT_LOCAL_SECRETS_JSON,\n// limited to the manifest's secrets. Edits recompile and swap the bundle.\n\nexport const DEFAULT_DEV_PORT = 3000;\n\nconst localSecretsSchema = z.record(z.string(), z.string());\n\n// node:http's address() for a TCP listener.\nconst listeningAddressSchema = z.object({ port: z.number() });\n\nexport const parseLocalSecrets = (text: string | undefined): Record<string, string> | null => {\n if (text == null || text.length === 0) return {};\n try {\n const parsed = localSecretsSchema.safeParse(JSON.parse(text));\n return parsed.success ? parsed.data : null;\n } catch {\n return null;\n }\n};\n\nconst previewInput = (input: JsonValue): string =>\n JSON.stringify(input, (key, value: unknown) =>\n /^(?:token|access_token|refresh_token|id_token|client_secret|clientSecret|signingSecret|authorization|response_url)$/i.test(\n key,\n )\n ? '[redacted]'\n : value,\n );\n\ninterface LoadedAgentIface {\n manifest: AgentManifestIface;\n bundle: LoadedBundleIface | null;\n // Channel stem \u2192 bundle export, for the custom channels the bundle serves.\n channels: Map<string, string>;\n routes: { stem: string; method: string; path: string }[];\n}\n\nexport interface DevServerArgsIface {\n dir: string;\n port: number;\n hostname?: string;\n secrets: Record<string, string>;\n apps?: Record<string, InstalledAppInfoIface>;\n output: OutputIface;\n // The isolate realm's fetch (tests).\n fetch?: typeof fetch;\n}\n\nexport interface DevServerIface {\n url: string;\n // Recompiles; false (and the previous bundle kept) when the compile fails.\n reload(): Promise<boolean>;\n close(): Promise<void>;\n}\n\nconst readBody = async (request: IncomingMessage): Promise<Buffer> => {\n const chunks: Buffer[] = [];\n for await (const chunk of request) chunks.push(Buffer.from(chunk));\n return Buffer.concat(chunks);\n};\n\nconst toRequest = async (request: IncomingMessage, origin: string): Promise<Request> => {\n const method = request.method ?? 'GET';\n const headers = new Headers();\n for (const [name, value] of Object.entries(request.headers)) {\n if (value == null) continue;\n for (const item of Array.isArray(value) ? value : [value]) headers.append(name, item);\n }\n const body = method === 'GET' || method === 'HEAD' ? null : await readBody(request);\n return new Request(new URL(request.url ?? '/', origin), {\n method,\n headers,\n body: body == null || body.byteLength === 0 ? null : new Uint8Array(body),\n });\n};\n\nconst writeResponse = async (response: Response, out: ServerResponse): Promise<void> => {\n out.statusCode = response.status;\n response.headers.forEach((value, name) => out.setHeader(name, value));\n out.end(Buffer.from(await response.arrayBuffer()));\n};\n\nconst plain = (out: ServerResponse, status: number, text: string): void => {\n out.statusCode = status;\n out.setHeader('content-type', 'text/plain; charset=utf-8');\n out.end(`${text}\\n`);\n};\n\n// `/<stem><path>`: the first segment names the channel, the rest is its route path.\nconst splitPath = (pathname: string): { stem: string; path: string } | null => {\n const match = /^\\/([^/]+)(\\/.*)?$/.exec(pathname);\n if (match?.[1] == null) return null;\n return { stem: decodeURIComponent(match[1]), path: match[2] ?? '/' };\n};\n\nconst loadAgent = async (args: {\n dir: string;\n output: OutputIface;\n fetch?: typeof fetch;\n}): Promise<LoadedAgentIface | null> => {\n const result = await compile({ dir: args.dir, previewBundle: true });\n for (const item of result.diagnostics) {\n (item.severity === DiagnosticSeverity.Error ? args.output.stderr : args.output.stdout)(\n diagnosticLine(item),\n );\n }\n if (hasErrors(result.diagnostics) || result.manifest == null) return null;\n const bundle =\n result.bundle == null\n ? null\n : await loadBundleInLocalIsolate(\n result.bundle.code,\n args.fetch == null ? {} : { fetch: args.fetch },\n );\n const channels = new Map<string, string>();\n const routes: LoadedAgentIface['routes'] = [];\n for (const binding of result.manifest.channels) {\n const source = result.manifest.channelSources?.[binding.key]?.path;\n const exportName =\n binding.channel.kind === ProviderRefKind.Bundle\n ? binding.channel.export\n : source?.replace(/\\.[cm]?[jt]sx?$/, '');\n if (exportName == null) continue;\n channels.set(binding.key, exportName);\n for (const route of binding.surface.routes) {\n routes.push({ stem: binding.key, method: route.method, path: route.path });\n }\n }\n return { manifest: result.manifest, bundle, channels, routes };\n};\n\nexport const startDevServer = async (args: DevServerArgsIface): Promise<DevServerIface> => {\n const { output } = args;\n let agent: LoadedAgentIface | null = null;\n let origin = '';\n\n const printRoutes = (): void => {\n if (agent == null) return;\n if (agent.routes.length === 0) {\n output.stdout('no custom channel routes (channels/*.ts) to serve');\n return;\n }\n for (const route of agent.routes) {\n output.stdout(` ${route.method} ${origin}/${route.stem}${route.path}`);\n }\n };\n\n const reload = async (): Promise<boolean> => {\n const next = await loadAgent({ dir: args.dir, output, fetch: args.fetch });\n if (next == null) {\n output.stderr(\n agent == null ? 'compile failed' : 'compile failed; still serving the last bundle',\n );\n return false;\n }\n agent = next;\n return true;\n };\n\n const handle = async (request: IncomingMessage, out: ServerResponse): Promise<void> => {\n const current = agent;\n const target = splitPath(new URL(request.url ?? '/', origin).pathname);\n const exportName = target == null ? null : (current?.channels.get(target.stem) ?? null);\n if (current?.bundle == null || target == null || exportName == null) {\n plain(out, 404, 'no custom channel route here');\n return;\n }\n const allowed = new Set(current.manifest.secrets);\n const stem = target.stem;\n const appName = current.manifest.channels.find((binding) => binding.key === stem)?.credentials\n .app;\n const response = await current.bundle.runtime.handleChannelRoute({\n export: exportName,\n context: createLocalChannelContext({\n appInfo:\n appName == null || args.apps == null || !Object.hasOwn(args.apps, appName)\n ? undefined\n : args.apps[appName],\n secret: async (name) => {\n if (!allowed.has(name)) {\n output.stderr(\n `credentials.secret(${JSON.stringify(name)}): not in the manifest's secrets`,\n );\n return null;\n }\n return args.secrets[name] ?? null;\n },\n }),\n request: await toRequest(request, origin),\n path: target.path,\n secrets: {\n get: async (name) => {\n if (!allowed.has(name)) {\n output.stderr(`secrets.get(${JSON.stringify(name)}): not in the manifest's secrets`);\n return null;\n }\n return args.secrets[name] ?? null;\n },\n },\n receive: async (input: JsonValue) => {\n output.stdout(`receive (${stem}): ${previewInput(input)}`);\n return { conversationId: 'local' };\n },\n });\n if (response == null) {\n plain(out, 404, `no ${request.method ?? 'GET'} ${target.path} route on channel ${stem}`);\n return;\n }\n await writeResponse(response, out);\n };\n\n const server = createServer((request, out) => {\n handle(request, out).catch((cause: unknown) => {\n output.stderr(`route failed: ${cause instanceof Error ? cause.message : String(cause)}`);\n if (!out.headersSent) plain(out, 500, 'route failed');\n else out.end();\n });\n });\n const channelSockets = attachDevChannelSockets({\n server,\n log: output.stderr,\n open: async (incoming, signal) => {\n const current = agent;\n const target = splitPath(new URL(incoming.url ?? '/', origin).pathname);\n const exportName = target == null ? null : current?.channels.get(target.stem);\n if (current?.bundle == null || target == null || exportName == null)\n return {\n ok: false,\n response: new Response('No custom channel socket route', { status: 404 }),\n };\n const bundle = current.bundle;\n const appName = current.manifest.channels.find((binding) => binding.key === target.stem)\n ?.credentials.app;\n const allowed = new Set(current.manifest.secrets);\n const request = new Request(await toRequest(incoming, origin), { signal });\n return openChannelSocket({\n signal,\n context: {\n request,\n secrets: {\n get: async (name: string) => (allowed.has(name) ? (args.secrets[name] ?? null) : null),\n },\n receive: async (input: import('@finalai/agent-provider').JsonValue) => {\n output.stdout(`receive (${target.stem}): ${previewInput(input)}`);\n return { conversationId: 'local' };\n },\n },\n handler: async (ctx) => {\n const response = await bundle.runtime.handleChannelSocket({\n export: exportName,\n context: createLocalChannelContext({\n appInfo:\n appName == null || args.apps == null || !Object.hasOwn(args.apps, appName)\n ? undefined\n : args.apps[appName],\n secret: async (name) => {\n if (!allowed.has(name)) {\n output.stderr(\n `credentials.secret(${JSON.stringify(name)}): not in the manifest's secrets`,\n );\n return null;\n }\n return args.secrets[name] ?? null;\n },\n }),\n path: target.path,\n ...ctx,\n });\n return response === null\n ? new Response('No custom channel socket route', { status: 404 })\n : response;\n },\n });\n },\n });\n const hostname = args.hostname ?? 'localhost';\n await new Promise<void>((done, fail) => {\n server.once('error', fail);\n server.listen(args.port, hostname, () => {\n server.off('error', fail);\n done();\n });\n });\n const port = listeningAddressSchema.safeParse(server.address()).data?.port ?? args.port;\n origin = `http://${hostname}:${port}`;\n await reload();\n output.stdout(`serving ${args.dir} at ${origin}`);\n printRoutes();\n\n return {\n url: origin,\n reload: async () => {\n const ok = await reload();\n if (ok) printRoutes();\n return ok;\n },\n close: async () => {\n await channelSockets.close();\n await new Promise<void>((done) => {\n server.closeAllConnections();\n server.close(() => done());\n });\n },\n };\n};\n\nconst RECOMPILE_DEBOUNCE_MS = 150;\n\nconst isBuildOutput = (path: string): boolean =>\n path.startsWith('.final') || path.split(/[\\\\/]/).includes('node_modules');\n\nexport const runDev = async (args: {\n dir: string;\n port: number;\n env: Record<string, string | undefined>;\n output: OutputIface;\n signal: AbortSignal;\n}): Promise<number> => {\n const secrets = parseLocalSecrets(args.env['AGENT_LOCAL_SECRETS_JSON']);\n if (secrets == null) {\n args.output.stderr('error: AGENT_LOCAL_SECRETS_JSON must be a JSON object of name \u2192 value');\n return 2;\n }\n let apps: Record<string, InstalledAppInfoIface> = {};\n const metadata = args.env['AGENT_LOCAL_APP_INFO_JSON'];\n if (metadata != null) {\n try {\n apps = z\n .record(\n z.string().min(1),\n z.object({\n clientId: z.string(),\n clientSecret: z.string(),\n signingSecret: z.string().optional(),\n }),\n )\n .parse(JSON.parse(metadata));\n } catch {\n args.output.stderr(\n 'error: AGENT_LOCAL_APP_INFO_JSON must map app names to OAuth/signing metadata',\n );\n return 2;\n }\n }\n let server: DevServerIface;\n try {\n server = await startDevServer({\n dir: args.dir,\n port: args.port,\n secrets,\n apps,\n output: args.output,\n });\n } catch (cause) {\n args.output.stderr(`error: ${cause instanceof Error ? cause.message : String(cause)}`);\n return 1;\n }\n let timer: ReturnType<typeof setTimeout> | null = null;\n let watcher: FSWatcher | null = null;\n try {\n watcher = watch(args.dir, { recursive: true }, (_event, file) => {\n if (file != null && isBuildOutput(file)) return;\n if (timer != null) clearTimeout(timer);\n timer = setTimeout(() => {\n args.output.stdout('change detected; recompiling');\n void server.reload();\n }, RECOMPILE_DEBOUNCE_MS);\n });\n } catch (cause) {\n args.output.stderr(\n `not watching for changes: ${cause instanceof Error ? cause.message : String(cause)}`,\n );\n }\n await new Promise<void>((done) => {\n if (args.signal.aborted) done();\n else args.signal.addEventListener('abort', () => done(), { once: true });\n });\n if (timer != null) clearTimeout(timer);\n watcher?.close();\n await server.close();\n return 0;\n};\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { createLocalChannelContext } from '@finalai/agent-provider/local-channel-context';\nimport {\n DiagnosticSeverity,\n hasErrors,\n loadBundleInLocalIsolate,\n type LoadedBundleIface,\n} from '@finalai/agent-definition/compiler';\nimport {\n ProviderRefKind,\n type AgentManifestIface,\n type JsonValue,\n type ChannelCredentialsIface,\n} from '@finalai/agent-provider';\nimport { openChannelSocket } from '@finalai/agent-provider/local-channel-socket';\nimport { watch, type FSWatcher } from 'node:fs';\nimport { createServer, type IncomingMessage, type ServerResponse } from 'node:http';\nimport * as z from 'zod';\nimport { compile } from \"../compile.mjs\";\nimport { attachDevChannelSockets } from \"./channel-socket.mjs\";\nimport { diagnosticLine, type OutputIface } from \"./output.mjs\";\n\n// Local HTTP and WebSocket previews serve declared channel routes.\n// Routes run in a local stand-in for the Worker isolate (a realm with Worker\n// globals only). There is no platform behind it: `receive` prints what the\n// route would deliver. credentials.secret reads declared channel secrets from\n// AGENT_LOCAL_SECRETS_JSON. Edits recompile and swap the bundle.\n\nexport const DEFAULT_DEV_PORT = 3000;\n\nconst localSecretsSchema = z.record(z.string(), z.string());\n\n// node:http's address() for a TCP listener.\nconst listeningAddressSchema = z.object({ port: z.number() });\n\nexport const parseLocalSecrets = (text: string | undefined): Record<string, string> | null => {\n if (text == null || text.length === 0) return {};\n try {\n const parsed = localSecretsSchema.safeParse(JSON.parse(text));\n return parsed.success ? parsed.data : null;\n } catch {\n return null;\n }\n};\n\nconst previewInput = (input: JsonValue): string =>\n JSON.stringify(input, (key, value: unknown) =>\n /^(?:token|access_token|refresh_token|id_token|client_secret|clientSecret|signingSecret|authorization|response_url)$/i.test(\n key,\n )\n ? '[redacted]'\n : value,\n );\n\ninterface LoadedAgentIface {\n manifest: AgentManifestIface;\n bundle: LoadedBundleIface | null;\n // Channel stem \u2192 bundle export, for the custom channels the bundle serves.\n channels: Map<string, string>;\n routes: { stem: string; method: string; path: string }[];\n}\n\nexport interface DevServerArgsIface {\n dir: string;\n port: number;\n hostname?: string;\n secrets: Record<string, string>;\n credentials?: Record<string, ChannelCredentialsIface>;\n output: OutputIface;\n // The isolate realm's fetch (tests).\n fetch?: typeof fetch;\n}\n\nexport interface DevServerIface {\n url: string;\n // Recompiles; false (and the previous bundle kept) when the compile fails.\n reload(): Promise<boolean>;\n close(): Promise<void>;\n}\n\nconst readBody = async (request: IncomingMessage): Promise<Buffer> => {\n const chunks: Buffer[] = [];\n for await (const chunk of request) chunks.push(Buffer.from(chunk));\n return Buffer.concat(chunks);\n};\n\nconst toRequest = async (request: IncomingMessage, origin: string): Promise<Request> => {\n const method = request.method ?? 'GET';\n const headers = new Headers();\n for (const [name, value] of Object.entries(request.headers)) {\n if (value == null) continue;\n for (const item of Array.isArray(value) ? value : [value]) headers.append(name, item);\n }\n const body = method === 'GET' || method === 'HEAD' ? null : await readBody(request);\n return new Request(new URL(request.url ?? '/', origin), {\n method,\n headers,\n body: body == null || body.byteLength === 0 ? null : new Uint8Array(body),\n });\n};\n\nconst writeResponse = async (response: Response, out: ServerResponse): Promise<void> => {\n out.statusCode = response.status;\n response.headers.forEach((value, name) => out.setHeader(name, value));\n out.end(Buffer.from(await response.arrayBuffer()));\n};\n\nconst plain = (out: ServerResponse, status: number, text: string): void => {\n out.statusCode = status;\n out.setHeader('content-type', 'text/plain; charset=utf-8');\n out.end(`${text}\\n`);\n};\n\n// `/<stem><path>`: the first segment names the channel, the rest is its route path.\nconst splitPath = (pathname: string): { stem: string; path: string } | null => {\n const match = /^\\/([^/]+)(\\/.*)?$/.exec(pathname);\n if (match?.[1] == null) return null;\n return { stem: decodeURIComponent(match[1]), path: match[2] ?? '/' };\n};\n\nconst loadAgent = async (args: {\n dir: string;\n output: OutputIface;\n fetch?: typeof fetch;\n}): Promise<LoadedAgentIface | null> => {\n const result = await compile({ dir: args.dir, previewBundle: true });\n for (const item of result.diagnostics) {\n (item.severity === DiagnosticSeverity.Error ? args.output.stderr : args.output.stdout)(\n diagnosticLine(item),\n );\n }\n if (hasErrors(result.diagnostics) || result.manifest == null) return null;\n const bundle =\n result.bundle == null\n ? null\n : await loadBundleInLocalIsolate(\n result.bundle.code,\n args.fetch == null ? {} : { fetch: args.fetch },\n );\n const channels = new Map<string, string>();\n const routes: LoadedAgentIface['routes'] = [];\n for (const binding of result.manifest.channels) {\n const source = result.manifest.channelSources?.[binding.key]?.path;\n const exportName =\n binding.channel.kind === ProviderRefKind.Bundle\n ? binding.channel.export\n : source?.replace(/\\.[cm]?[jt]sx?$/, '');\n if (exportName == null) continue;\n channels.set(binding.key, exportName);\n for (const route of binding.surface.routes) {\n routes.push({ stem: binding.key, method: route.method, path: route.path });\n }\n }\n return { manifest: result.manifest, bundle, channels, routes };\n};\n\nexport const startDevServer = async (args: DevServerArgsIface): Promise<DevServerIface> => {\n const { output } = args;\n let agent: LoadedAgentIface | null = null;\n let origin = '';\n\n const printRoutes = (): void => {\n if (agent == null) return;\n if (agent.routes.length === 0) {\n output.stdout('no custom channel routes (channels/*.ts) to serve');\n return;\n }\n for (const route of agent.routes) {\n output.stdout(` ${route.method} ${origin}/${route.stem}${route.path}`);\n }\n };\n\n const reload = async (): Promise<boolean> => {\n const next = await loadAgent({ dir: args.dir, output, fetch: args.fetch });\n if (next == null) {\n output.stderr(\n agent == null ? 'compile failed' : 'compile failed; still serving the last bundle',\n );\n return false;\n }\n agent = next;\n return true;\n };\n\n const handle = async (request: IncomingMessage, out: ServerResponse): Promise<void> => {\n const current = agent;\n const target = splitPath(new URL(request.url ?? '/', origin).pathname);\n const exportName = target == null ? null : (current?.channels.get(target.stem) ?? null);\n if (current?.bundle == null || target == null || exportName == null) {\n plain(out, 404, 'no custom channel route here');\n return;\n }\n const allowed = new Set(current.manifest.secrets);\n const stem = target.stem;\n const selected = current.manifest.channels.find((binding) => binding.key === stem);\n const appName = selected?.credentials.app;\n const declared = new Set(selected?.credentials.secrets ?? []);\n const response = await current.bundle.runtime.handleChannelRoute({\n export: exportName,\n context: createLocalChannelContext({\n url: `${origin}/${stem}`,\n credentials:\n appName == null || args.credentials == null || !Object.hasOwn(args.credentials, appName)\n ? undefined\n : args.credentials[appName],\n secret: async (name) => {\n if (!allowed.has(name)) {\n output.stderr(\n `credentials.secret(${JSON.stringify(name)}): not in the manifest's secrets`,\n );\n return null;\n }\n if (!declared.has(name)) {\n output.stderr(\n `credentials.secret(${JSON.stringify(name)}): not in this channel's declared secrets`,\n );\n return null;\n }\n return args.secrets[name] ?? null;\n },\n }),\n request: await toRequest(request, origin),\n path: target.path,\n receive: async (input: JsonValue) => {\n output.stdout(`receive (${stem}): ${previewInput(input)}`);\n return { conversationId: 'local' };\n },\n });\n if (response == null) {\n plain(out, 404, `no ${request.method ?? 'GET'} ${target.path} route on channel ${stem}`);\n return;\n }\n await writeResponse(response, out);\n };\n\n const server = createServer((request, out) => {\n handle(request, out).catch((cause: unknown) => {\n output.stderr(`route failed: ${cause instanceof Error ? cause.message : String(cause)}`);\n if (!out.headersSent) plain(out, 500, 'route failed');\n else out.end();\n });\n });\n const channelSockets = attachDevChannelSockets({\n server,\n log: output.stderr,\n open: async (incoming, signal) => {\n const current = agent;\n const target = splitPath(new URL(incoming.url ?? '/', origin).pathname);\n const exportName = target == null ? null : current?.channels.get(target.stem);\n if (current?.bundle == null || target == null || exportName == null)\n return {\n ok: false,\n response: new Response('No custom channel socket route', { status: 404 }),\n };\n const bundle = current.bundle;\n const selected = current.manifest.channels.find((binding) => binding.key === target.stem);\n const appName = selected?.credentials.app;\n const declared = new Set(selected?.credentials.secrets ?? []);\n const allowed = new Set(current.manifest.secrets);\n const request = new Request(await toRequest(incoming, origin), { signal });\n return openChannelSocket({\n signal,\n context: {\n request,\n receive: async (input: import('@finalai/agent-provider').JsonValue) => {\n output.stdout(`receive (${target.stem}): ${previewInput(input)}`);\n return { conversationId: 'local' };\n },\n },\n handler: async (ctx) => {\n const response = await bundle.runtime.handleChannelSocket({\n export: exportName,\n context: createLocalChannelContext({\n url: `${origin}/${target.stem}`,\n credentials:\n appName == null ||\n args.credentials == null ||\n !Object.hasOwn(args.credentials, appName)\n ? undefined\n : args.credentials[appName],\n secret: async (name) => {\n if (!allowed.has(name)) {\n output.stderr(\n `credentials.secret(${JSON.stringify(name)}): not in the manifest's secrets`,\n );\n return null;\n }\n if (!declared.has(name)) {\n output.stderr(\n `credentials.secret(${JSON.stringify(name)}): not in this channel's declared secrets`,\n );\n return null;\n }\n return args.secrets[name] ?? null;\n },\n }),\n path: target.path,\n ...ctx,\n });\n return response === null\n ? new Response('No custom channel socket route', { status: 404 })\n : response;\n },\n });\n },\n });\n const hostname = args.hostname ?? 'localhost';\n await new Promise<void>((done, fail) => {\n server.once('error', fail);\n server.listen(args.port, hostname, () => {\n server.off('error', fail);\n done();\n });\n });\n const port = listeningAddressSchema.safeParse(server.address()).data?.port ?? args.port;\n origin = `http://${hostname}:${port}`;\n await reload();\n output.stdout(`serving ${args.dir} at ${origin}`);\n printRoutes();\n\n return {\n url: origin,\n reload: async () => {\n const ok = await reload();\n if (ok) printRoutes();\n return ok;\n },\n close: async () => {\n await channelSockets.close();\n await new Promise<void>((done) => {\n server.closeAllConnections();\n server.close(() => done());\n });\n },\n };\n};\n\nconst RECOMPILE_DEBOUNCE_MS = 150;\n\nconst isBuildOutput = (path: string): boolean =>\n path.startsWith('.final') || path.split(/[\\\\/]/).includes('node_modules');\n\nexport const runDev = async (args: {\n dir: string;\n port: number;\n env: Record<string, string | undefined>;\n output: OutputIface;\n signal: AbortSignal;\n}): Promise<number> => {\n const secrets = parseLocalSecrets(args.env['AGENT_LOCAL_SECRETS_JSON']);\n if (secrets == null) {\n args.output.stderr('error: AGENT_LOCAL_SECRETS_JSON must be a JSON object of name \u2192 value');\n return 2;\n }\n let server: DevServerIface;\n try {\n server = await startDevServer({\n dir: args.dir,\n port: args.port,\n secrets,\n output: args.output,\n });\n } catch (cause) {\n args.output.stderr(`error: ${cause instanceof Error ? cause.message : String(cause)}`);\n return 1;\n }\n let timer: ReturnType<typeof setTimeout> | null = null;\n let watcher: FSWatcher | null = null;\n try {\n watcher = watch(args.dir, { recursive: true }, (_event, file) => {\n if (file != null && isBuildOutput(file)) return;\n if (timer != null) clearTimeout(timer);\n timer = setTimeout(() => {\n args.output.stdout('change detected; recompiling');\n void server.reload();\n }, RECOMPILE_DEBOUNCE_MS);\n });\n } catch (cause) {\n args.output.stderr(\n `not watching for changes: ${cause instanceof Error ? cause.message : String(cause)}`,\n );\n }\n await new Promise<void>((done) => {\n if (args.signal.aborted) done();\n else args.signal.addEventListener('abort', () => done(), { once: true });\n });\n if (timer != null) clearTimeout(timer);\n watcher?.close();\n await server.close();\n return 0;\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -67,7 +67,7 @@ const errorLines = (cause) => {
|
|
|
67
67
|
const publishResultLines = (result) => {
|
|
68
68
|
const revision = result.revision;
|
|
69
69
|
const lines = [
|
|
70
|
-
`${result.created ? "published" : "already
|
|
70
|
+
`${result.created ? "published" : "already published"}: revision ${revision.number} (${revision.id})`,
|
|
71
71
|
`commit: ${revision.commitSha ?? "unknown"}`,
|
|
72
72
|
`bundle: ${revision.bundleHash ?? "none"}`
|
|
73
73
|
];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/cli/output.ts"],
|
|
4
|
-
"sourcesContent": ["import type { CompatibilityReportIface } from '@finalai/agent-definition/compatibility';\nimport type { DiagnosticIface } from '@finalai/agent-definition/compiler';\nimport {\n findDynamicSlots,\n formatProviderRef,\n isDynamicSlot,\n type AgentManifestIface,\n} from '@finalai/agent-provider';\nimport * as z from 'zod';\nimport { isClientError } from \"../agent-client/errors.mjs\";\nimport { diagnosticSchema, type PublishResultIface } from \"../agent-client/index.mjs\";\n\nexport interface OutputIface {\n stdout: (line: string) => void;\n stderr: (line: string) => void;\n}\n\nconst listOrNone = (items: readonly string[]): string =>\n items.length === 0 ? 'none' : items.join(', ');\n\nexport const manifestSummaryLines = (manifest: AgentManifestIface): string[] => {\n const lines = [`agent: ${manifest.identity.name}`];\n if (manifest.identity.description != null)\n lines.push(`description: ${manifest.identity.description}`);\n lines.push(`harness: ${formatProviderRef(manifest.harness.harness)}`);\n lines.push(\n `mcp servers: ${\n isDynamicSlot(manifest.mcpServers)\n ? 'dynamic'\n : listOrNone(manifest.mcpServers.map((server) => `${server.key} (${server.kind})`))\n }`,\n );\n lines.push(\n `sandboxes: ${\n isDynamicSlot(manifest.sandboxes) ? 'dynamic' : listOrNone(Object.keys(manifest.sandboxes))\n }`,\n );\n lines.push(\n `base tools: ${listOrNone(\n Object.entries(manifest.tools.base).map(\n ([capability, binding]) => `${capability} \u2192 ${binding?.target ?? '?'}`,\n ),\n )}`,\n );\n lines.push(`channels: ${listOrNone(manifest.channels.map((channel) => channel.key))}`);\n lines.push(\n `schedules: ${listOrNone(\n manifest.schedules.map(\n (schedule) => `${schedule.key} (${schedule.cron}, ${schedule.timezone})`,\n ),\n )}`,\n );\n lines.push(`secrets: ${listOrNone(manifest.secrets)}`);\n lines.push(`dynamic slots: ${listOrNone(findDynamicSlots(manifest).map((slot) => slot.path))}`);\n lines.push(`bundle: ${manifest.bundle?.hash ?? 'none'}`);\n return lines;\n};\n\nexport const hookLines = (manifest: AgentManifestIface): string[] =>\n manifest.hooks.length === 0\n ? ['hooks: none']\n : [\n 'hooks:',\n ...manifest.hooks.map(\n (hook) => ` ${hook.slug} (${hook.export}): ${hook.events.join(', ')}`,\n ),\n ];\n\nexport const reportLines = (report: CompatibilityReportIface): string[] => [\n `compatibility with ${formatProviderRef(report.harness)}: ${report.ok ? 'ok' : 'incompatible'}`,\n ...report.rows.map((row) => ` ${row.item}: ${row.result} (${row.why})`),\n];\n\nexport const diagnosticLine = (item: DiagnosticIface): string =>\n `${item.severity}: ${item.path == null ? '' : `${item.path}: `}${item.message} [${item.code}]`;\n\nconst errorDiagnosticsSchema = z.object({\n error: z.object({\n details: z.object({ diagnostics: z.array(diagnosticSchema) }).nullable(),\n }),\n});\n\n// SDK errors with the server's compile diagnostics, when it sent any.\nexport const errorLines = (cause: unknown): string[] => {\n if (!isClientError(cause))\n return [`error: ${cause instanceof Error ? cause.message : String(cause)}`];\n const lines = [`error: ${cause.message}${cause.status === 0 ? '' : ` (HTTP ${cause.status})`}`];\n const parsed = errorDiagnosticsSchema.safeParse(cause.body);\n for (const item of parsed.success ? (parsed.data.error.details?.diagnostics ?? []) : []) {\n lines.push(` ${item.severity}: ${item.file == null ? '' : `${item.file}: `}${item.message}`);\n }\n return lines;\n};\n\nexport const publishResultLines = (result: PublishResultIface): string[] => {\n const revision = result.revision;\n const lines = [\n `${result.created ? 'published' : 'already
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import type { CompatibilityReportIface } from '@finalai/agent-definition/compatibility';\nimport type { DiagnosticIface } from '@finalai/agent-definition/compiler';\nimport {\n findDynamicSlots,\n formatProviderRef,\n isDynamicSlot,\n type AgentManifestIface,\n} from '@finalai/agent-provider';\nimport * as z from 'zod';\nimport { isClientError } from \"../agent-client/errors.mjs\";\nimport { diagnosticSchema, type PublishResultIface } from \"../agent-client/index.mjs\";\n\nexport interface OutputIface {\n stdout: (line: string) => void;\n stderr: (line: string) => void;\n}\n\nconst listOrNone = (items: readonly string[]): string =>\n items.length === 0 ? 'none' : items.join(', ');\n\nexport const manifestSummaryLines = (manifest: AgentManifestIface): string[] => {\n const lines = [`agent: ${manifest.identity.name}`];\n if (manifest.identity.description != null)\n lines.push(`description: ${manifest.identity.description}`);\n lines.push(`harness: ${formatProviderRef(manifest.harness.harness)}`);\n lines.push(\n `mcp servers: ${\n isDynamicSlot(manifest.mcpServers)\n ? 'dynamic'\n : listOrNone(manifest.mcpServers.map((server) => `${server.key} (${server.kind})`))\n }`,\n );\n lines.push(\n `sandboxes: ${\n isDynamicSlot(manifest.sandboxes) ? 'dynamic' : listOrNone(Object.keys(manifest.sandboxes))\n }`,\n );\n lines.push(\n `base tools: ${listOrNone(\n Object.entries(manifest.tools.base).map(\n ([capability, binding]) => `${capability} \u2192 ${binding?.target ?? '?'}`,\n ),\n )}`,\n );\n lines.push(`channels: ${listOrNone(manifest.channels.map((channel) => channel.key))}`);\n lines.push(\n `schedules: ${listOrNone(\n manifest.schedules.map(\n (schedule) => `${schedule.key} (${schedule.cron}, ${schedule.timezone})`,\n ),\n )}`,\n );\n lines.push(`secrets: ${listOrNone(manifest.secrets)}`);\n lines.push(`dynamic slots: ${listOrNone(findDynamicSlots(manifest).map((slot) => slot.path))}`);\n lines.push(`bundle: ${manifest.bundle?.hash ?? 'none'}`);\n return lines;\n};\n\nexport const hookLines = (manifest: AgentManifestIface): string[] =>\n manifest.hooks.length === 0\n ? ['hooks: none']\n : [\n 'hooks:',\n ...manifest.hooks.map(\n (hook) => ` ${hook.slug} (${hook.export}): ${hook.events.join(', ')}`,\n ),\n ];\n\nexport const reportLines = (report: CompatibilityReportIface): string[] => [\n `compatibility with ${formatProviderRef(report.harness)}: ${report.ok ? 'ok' : 'incompatible'}`,\n ...report.rows.map((row) => ` ${row.item}: ${row.result} (${row.why})`),\n];\n\nexport const diagnosticLine = (item: DiagnosticIface): string =>\n `${item.severity}: ${item.path == null ? '' : `${item.path}: `}${item.message} [${item.code}]`;\n\nconst errorDiagnosticsSchema = z.object({\n error: z.object({\n details: z.object({ diagnostics: z.array(diagnosticSchema) }).nullable(),\n }),\n});\n\n// SDK errors with the server's compile diagnostics, when it sent any.\nexport const errorLines = (cause: unknown): string[] => {\n if (!isClientError(cause))\n return [`error: ${cause instanceof Error ? cause.message : String(cause)}`];\n const lines = [`error: ${cause.message}${cause.status === 0 ? '' : ` (HTTP ${cause.status})`}`];\n const parsed = errorDiagnosticsSchema.safeParse(cause.body);\n for (const item of parsed.success ? (parsed.data.error.details?.diagnostics ?? []) : []) {\n lines.push(` ${item.severity}: ${item.file == null ? '' : `${item.file}: `}${item.message}`);\n }\n return lines;\n};\n\nexport const publishResultLines = (result: PublishResultIface): string[] => {\n const revision = result.revision;\n const lines = [\n `${result.created ? 'published' : 'already published'}: revision ${revision.number} (${revision.id})`,\n `commit: ${revision.commitSha ?? 'unknown'}`,\n `bundle: ${revision.bundleHash ?? 'none'}`,\n ];\n for (const item of result.diagnostics) lines.push(`${item.severity}: ${item.message}`);\n for (const channel of result.channels) {\n lines.push(`channel ${channel.key} (${channel.bindingId}):`);\n for (const route of channel.routes) {\n lines.push(` ${route.method} ${route.url ?? route.aliasUrl}`);\n if (route.url != null) lines.push(` alias: ${route.aliasUrl}`);\n }\n if (channel.webhookSecret != null)\n lines.push(` signing secret (shown once): ${channel.webhookSecret}`);\n }\n return lines;\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -75,8 +75,11 @@ const runPublish = async (args) => {
|
|
|
75
75
|
ref
|
|
76
76
|
};
|
|
77
77
|
if (args.note != null) request.note = args.note;
|
|
78
|
+
if (args.activate != null) request.activate = args.activate;
|
|
78
79
|
const result = await client.definitions.publish(request);
|
|
79
80
|
for (const line of publishResultLines(result)) output.stdout(line);
|
|
81
|
+
if (args.activate === false)
|
|
82
|
+
output.stdout("source-only: the live agent, routes, and schedules are unchanged");
|
|
80
83
|
return 0;
|
|
81
84
|
} catch (cause) {
|
|
82
85
|
for (const line of errorLines(cause)) output.stderr(line);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/cli/publish.ts"],
|
|
4
|
-
"sourcesContent": ["import type { AgentClientIface } from \"../agent-client/client.mjs\";\nimport { isClientError } from \"../agent-client/errors.mjs\";\nimport { DefinitionRepositoryKind, type DefinitionIface } from \"../agent-client/index.mjs\";\nimport { compileAndPrint } from \"./build.mjs\";\nimport { fileChanges, readLocalFiles, type ListFiles } from \"./files.mjs\";\nimport { errorLines, publishResultLines, type OutputIface } from \"./output.mjs\";\n\n// `final agents publish`: compiles the checkout\n// locally, commits it to the agent's default branch, and publishes that\n// commit. A GitHub-backed definition is not committed to; its ref (the\n// default branch unless given) is published as-is.\n\nexport interface PublishArgsIface {\n dir: string;\n // Definition slug or id.\n agent: string;\n // GitHub-backed definitions only.\n ref: string | null;\n message: string;\n note: string | null;\n client: AgentClientIface;\n listFiles: ListFiles;\n output: OutputIface;\n}\n\n// The default branch's files and head; an empty repository has neither.\nconst remoteFiles = async (args: {\n client: AgentClientIface;\n definition: DefinitionIface;\n branch: string;\n}): Promise<{ commitSha: string | null; files: Record<string, string> }> => {\n try {\n const listing = await args.client.definitions.files({\n definition: args.definition.id,\n ref: args.branch,\n });\n return {\n commitSha: listing.commitSha,\n files: Object.fromEntries(listing.files.map((file) => [file.path, file.content])),\n };\n } catch (cause) {\n if (isClientError(cause) && cause.status === 404) return { commitSha: null, files: {} };\n throw cause;\n }\n};\n\nconst commitCheckout = async (args: {\n publish: PublishArgsIface;\n definition: DefinitionIface;\n branch: string;\n local: Record<string, string>;\n}): Promise<string> => {\n const { client, output, message } = args.publish;\n const remote = await remoteFiles({ client, definition: args.definition, branch: args.branch });\n const changes = fileChanges({ local: args.local, remote: remote.files });\n if (changes.length === 0 && remote.commitSha != null) {\n output.stdout(`no changes; publishing ${args.branch} at ${remote.commitSha}`);\n return remote.commitSha;\n }\n const request: Parameters<AgentClientIface['definitions']['commit']>[0] = {\n definition: args.definition.id,\n files: changes,\n message,\n branch: args.branch,\n };\n // The commit fails if the branch moved since it was read.\n if (remote.commitSha != null) request.parentSha = remote.commitSha;\n const committed = await client.definitions.commit(request);\n const deleted = changes.filter((change) => change.content == null).length;\n output.stdout(\n `committed ${committed.commitSha} to ${committed.branch} (${changes.length - deleted} written, ${deleted} deleted)`,\n );\n return committed.commitSha;\n};\n\nexport const runPublish = async (args: PublishArgsIface): Promise<number> => {\n const { client, output } = args;\n try {\n const local = await readLocalFiles({ dir: args.dir, listFiles: args.listFiles });\n for (const problem of local.problems) output.stderr(`error: ${problem}`);\n if (local.problems.length > 0) return 1;\n\n // What the platform compiles is the committed files, so compile those.\n const compiled = await compileAndPrint({ source: { files: local.files }, client, output });\n if (!compiled.ok) {\n output.stderr('error: the agent did not compile; nothing was published');\n return 1;\n }\n\n const definition = await client.definitions.get({ definition: args.agent });\n const repository = definition.repository;\n const kind = repository?.kind ?? DefinitionRepositoryKind.CodeStorage;\n const branch = repository?.defaultBranch ?? 'main';\n let ref: string;\n if (kind === DefinitionRepositoryKind.GitHub) {\n ref = args.ref ?? branch;\n } else if (kind === DefinitionRepositoryKind.CodeStorage) {\n if (args.ref != null) {\n output.stderr(\n 'error: --ref applies to GitHub-backed agents; this agent is published from the checkout',\n );\n return 1;\n }\n ref = await commitCheckout({ publish: args, definition, branch, local: local.files });\n } else {\n output.stderr(`error: ${args.agent} uses a repository kind this CLI does not know`);\n return 1;\n }\n\n const request: Parameters<AgentClientIface['definitions']['publish']>[0] = {\n definition: definition.id,\n ref,\n };\n if (args.note != null) request.note = args.note;\n const result = await client.definitions.publish(request);\n for (const line of publishResultLines(result)) output.stdout(line);\n return 0;\n } catch (cause) {\n for (const line of errorLines(cause)) output.stderr(line);\n return 1;\n }\n};\n"],
|
|
5
|
-
"mappings": "AACA,SAAS,qBAAqB;AAC9B,SAAS,gCAAsD;AAC/D,SAAS,uBAAuB;AAChC,SAAS,aAAa,sBAAsC;AAC5D,SAAS,YAAY,0BAA4C;
|
|
4
|
+
"sourcesContent": ["import type { AgentClientIface } from \"../agent-client/client.mjs\";\nimport { isClientError } from \"../agent-client/errors.mjs\";\nimport { DefinitionRepositoryKind, type DefinitionIface } from \"../agent-client/index.mjs\";\nimport { compileAndPrint } from \"./build.mjs\";\nimport { fileChanges, readLocalFiles, type ListFiles } from \"./files.mjs\";\nimport { errorLines, publishResultLines, type OutputIface } from \"./output.mjs\";\n\n// `final agents publish`: compiles the checkout\n// locally, commits it to the agent's default branch, and publishes that\n// commit. A GitHub-backed definition is not committed to; its ref (the\n// default branch unless given) is published as-is.\n\nexport interface PublishArgsIface {\n dir: string;\n // Definition slug or id.\n agent: string;\n // GitHub-backed definitions only.\n ref: string | null;\n message: string;\n note: string | null;\n activate?: boolean;\n client: AgentClientIface;\n listFiles: ListFiles;\n output: OutputIface;\n}\n\n// The default branch's files and head; an empty repository has neither.\nconst remoteFiles = async (args: {\n client: AgentClientIface;\n definition: DefinitionIface;\n branch: string;\n}): Promise<{ commitSha: string | null; files: Record<string, string> }> => {\n try {\n const listing = await args.client.definitions.files({\n definition: args.definition.id,\n ref: args.branch,\n });\n return {\n commitSha: listing.commitSha,\n files: Object.fromEntries(listing.files.map((file) => [file.path, file.content])),\n };\n } catch (cause) {\n if (isClientError(cause) && cause.status === 404) return { commitSha: null, files: {} };\n throw cause;\n }\n};\n\nconst commitCheckout = async (args: {\n publish: PublishArgsIface;\n definition: DefinitionIface;\n branch: string;\n local: Record<string, string>;\n}): Promise<string> => {\n const { client, output, message } = args.publish;\n const remote = await remoteFiles({ client, definition: args.definition, branch: args.branch });\n const changes = fileChanges({ local: args.local, remote: remote.files });\n if (changes.length === 0 && remote.commitSha != null) {\n output.stdout(`no changes; publishing ${args.branch} at ${remote.commitSha}`);\n return remote.commitSha;\n }\n const request: Parameters<AgentClientIface['definitions']['commit']>[0] = {\n definition: args.definition.id,\n files: changes,\n message,\n branch: args.branch,\n };\n // The commit fails if the branch moved since it was read.\n if (remote.commitSha != null) request.parentSha = remote.commitSha;\n const committed = await client.definitions.commit(request);\n const deleted = changes.filter((change) => change.content == null).length;\n output.stdout(\n `committed ${committed.commitSha} to ${committed.branch} (${changes.length - deleted} written, ${deleted} deleted)`,\n );\n return committed.commitSha;\n};\n\nexport const runPublish = async (args: PublishArgsIface): Promise<number> => {\n const { client, output } = args;\n try {\n const local = await readLocalFiles({ dir: args.dir, listFiles: args.listFiles });\n for (const problem of local.problems) output.stderr(`error: ${problem}`);\n if (local.problems.length > 0) return 1;\n\n // What the platform compiles is the committed files, so compile those.\n const compiled = await compileAndPrint({ source: { files: local.files }, client, output });\n if (!compiled.ok) {\n output.stderr('error: the agent did not compile; nothing was published');\n return 1;\n }\n\n const definition = await client.definitions.get({ definition: args.agent });\n const repository = definition.repository;\n const kind = repository?.kind ?? DefinitionRepositoryKind.CodeStorage;\n const branch = repository?.defaultBranch ?? 'main';\n let ref: string;\n if (kind === DefinitionRepositoryKind.GitHub) {\n ref = args.ref ?? branch;\n } else if (kind === DefinitionRepositoryKind.CodeStorage) {\n if (args.ref != null) {\n output.stderr(\n 'error: --ref applies to GitHub-backed agents; this agent is published from the checkout',\n );\n return 1;\n }\n ref = await commitCheckout({ publish: args, definition, branch, local: local.files });\n } else {\n output.stderr(`error: ${args.agent} uses a repository kind this CLI does not know`);\n return 1;\n }\n\n const request: Parameters<AgentClientIface['definitions']['publish']>[0] = {\n definition: definition.id,\n ref,\n };\n if (args.note != null) request.note = args.note;\n if (args.activate != null) request.activate = args.activate;\n const result = await client.definitions.publish(request);\n for (const line of publishResultLines(result)) output.stdout(line);\n if (args.activate === false)\n output.stdout('source-only: the live agent, routes, and schedules are unchanged');\n return 0;\n } catch (cause) {\n for (const line of errorLines(cause)) output.stderr(line);\n return 1;\n }\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/modules/compile.mjs
CHANGED
|
@@ -18,13 +18,6 @@ const compile = async (options) => {
|
|
|
18
18
|
"sandboxes/environment",
|
|
19
19
|
"connections",
|
|
20
20
|
"channels/final",
|
|
21
|
-
"channels/slack",
|
|
22
|
-
"channels/discord",
|
|
23
|
-
"channels/github",
|
|
24
|
-
"channels/linear",
|
|
25
|
-
"channels/webhook",
|
|
26
|
-
"channels/voice",
|
|
27
|
-
"channels/phone",
|
|
28
21
|
"channel-factories"
|
|
29
22
|
].map((path) => "@finalai/final-agent-provider/" + path);
|
|
30
23
|
const providerModules = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/compile.ts"],
|
|
4
|
-
"sourcesContent": ["import type { CompileOptionsIface, CompileResultIface } from '@finalai/agent-definition/compiler';\nimport { fileURLToPath } from 'node:url';\nexport const compile = async (options: CompileOptionsIface): Promise<CompileResultIface> => {\n const finalAuthoringModules = [\n 'harnesses',\n 'harnesses/config-fields',\n 'harnesses/serverless-final',\n 'harnesses/serverless-pi',\n 'harnesses/serverless-nanocode-codex',\n 'harnesses/serverless-nanocode-claude',\n 'harnesses/remote-pi',\n 'harnesses/remote-codex',\n 'harnesses/remote-claude-code',\n 'harnesses/remote-acp',\n 'harnesses/local-stdio',\n 'sandboxes',\n 'sandboxes/computer',\n 'sandboxes/device',\n 'sandboxes/environment',\n 'connections',\n 'channels/final',\n '
|
|
5
|
-
"mappings": "AACA,SAAS,qBAAqB;AACvB,MAAM,UAAU,OAAO,YAA8D;AAC1F,QAAM,wBAAwB;AAAA,IAC5B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,
|
|
4
|
+
"sourcesContent": ["import type { CompileOptionsIface, CompileResultIface } from '@finalai/agent-definition/compiler';\nimport { fileURLToPath } from 'node:url';\nexport const compile = async (options: CompileOptionsIface): Promise<CompileResultIface> => {\n const finalAuthoringModules = [\n 'harnesses',\n 'harnesses/config-fields',\n 'harnesses/serverless-final',\n 'harnesses/serverless-pi',\n 'harnesses/serverless-nanocode-codex',\n 'harnesses/serverless-nanocode-claude',\n 'harnesses/remote-pi',\n 'harnesses/remote-codex',\n 'harnesses/remote-claude-code',\n 'harnesses/remote-acp',\n 'harnesses/local-stdio',\n 'sandboxes',\n 'sandboxes/computer',\n 'sandboxes/device',\n 'sandboxes/environment',\n 'connections',\n 'channels/final',\n 'channel-factories',\n ].map((path) => '@finalai/final-agent-provider/' + path);\n const providerModules = {\n ...Object.fromEntries(\n finalAuthoringModules.map((specifier) => [\n specifier,\n fileURLToPath(import.meta.resolve(specifier)),\n ]),\n ),\n '@finalai/agents': fileURLToPath(import.meta.resolve('@finalai/agents/authoring')),\n '@finalai/agents/harnesses': fileURLToPath(\n import.meta.resolve('@finalai/final-agent-provider/harnesses'),\n ),\n '@finalai/agents/sandboxes': fileURLToPath(\n import.meta.resolve('@finalai/final-agent-provider/sandboxes'),\n ),\n '@finalai/agents/channels/final': fileURLToPath(\n import.meta.resolve('@finalai/final-agent-provider/channels/final'),\n ),\n ...options.providerModules,\n };\n return (await import('@finalai/agent-definition/compiler')).compile({\n defaultFiles: {\n 'channels/final.ts':\n \"import { finalChannel } from '@finalai/agents/channels/final'; export default finalChannel();\",\n },\n ...options,\n providerModules,\n installedSandboxProviders: {\n computer: '@finalai/final-agent-provider/sandboxes/computer',\n device: '@finalai/final-agent-provider/sandboxes/device',\n ...options.installedSandboxProviders,\n },\n });\n};\nexport type {\n CompatibilityReportIface,\n CompiledBundleIface,\n CompileOptionsIface,\n CompileResultIface,\n DiagnosticCode,\n DiagnosticIface,\n DiagnosticSeverity,\n HarnessDescriptionContextIface,\n} from '@finalai/agent-definition/compiler';\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,qBAAqB;AACvB,MAAM,UAAU,OAAO,YAA8D;AAC1F,QAAM,wBAAwB;AAAA,IAC5B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,IAAI,CAAC,SAAS,mCAAmC,IAAI;AACvD,QAAM,kBAAkB;AAAA,IACtB,GAAG,OAAO;AAAA,MACR,sBAAsB,IAAI,CAAC,cAAc;AAAA,QACvC;AAAA,QACA,cAAc,YAAY,QAAQ,SAAS,CAAC;AAAA,MAC9C,CAAC;AAAA,IACH;AAAA,IACA,mBAAmB,cAAc,YAAY,QAAQ,2BAA2B,CAAC;AAAA,IACjF,6BAA6B;AAAA,MAC3B,YAAY,QAAQ,yCAAyC;AAAA,IAC/D;AAAA,IACA,6BAA6B;AAAA,MAC3B,YAAY,QAAQ,yCAAyC;AAAA,IAC/D;AAAA,IACA,kCAAkC;AAAA,MAChC,YAAY,QAAQ,8CAA8C;AAAA,IACpE;AAAA,IACA,GAAG,QAAQ;AAAA,EACb;AACA,UAAQ,MAAM,OAAO,oCAAoC,GAAG,QAAQ;AAAA,IAClE,cAAc;AAAA,MACZ,qBACE;AAAA,IACJ;AAAA,IACA,GAAG;AAAA,IACH;AAAA,IACA,2BAA2B;AAAA,MACzB,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,GAAG,QAAQ;AAAA,IACb;AAAA,EACF,CAAC;AACH;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
export { CredentialOwner, CredentialPayer, DELETE, GET, HookEvent, POST, PUT, SandboxWire, WS, always, baseTools, credentials, defineAgent, defineChannel,
|
|
1
|
+
export { CredentialOwner, CredentialPayer, DELETE, GET, HookEvent, POST, PUT, SandboxWire, WS, always, baseTools, credentials, defineAgent, defineChannel, disableChannel, defineDynamic, defineHarness, defineHostedConnection, defineHook, defineInstructions, defineMcpClientConnection, defineSandbox, defineSandboxProvider, defineSchedule, defineSkill, defineTool, harnessHost, never, toolResultFrom, whenInput, } from "./authoring/index.mjs";
|
|
2
2
|
export type { AgentDefinitionInputIface, AgentSessionInfoIface, ApprovalPolicyIface, AuthoredChannelDefinitionIface, AuthoredHarnessCloseContextIface, AuthoredHarnessDescriptionIface, AuthoredHarnessEndpointIface, AuthoredHarnessHealthIface, AuthoredHarnessIface, AuthoredHarnessOpenArgsIface, AuthoredHarnessRefContextIface, AuthoredHarnessResumeArgsIface, BaseToolsValueIface, ConversationInfoIface, CredentialNode, CredentialPolicyIface, DefinedAuthoredHarnessIface, DefinedToolIface, DynamicDefinitionIface, DynamicResolveContextIface, DynamicSentinelIface, FinalPlatformClientIface, HarnessHostIface, HookContextIface, HookDefinitionIface, HookEventIface, HostedConnectionDefinitionIface, McpClientConnectionDefinitionIface, SandboxSelectorContextIface, ScheduleInputIface, SkillDefinitionIface, ToolContextIface, ToolDefinitionIface, } from "./authoring/index.mjs";
|
|
3
3
|
export * from "./authoring/providers.mjs";
|
|
4
|
-
export type { AgentAvatarIface, AvatarMedia, AvatarState, AgentManifestIface, ChannelDefinitionIface, ChannelReceiveContextIface, ChannelEventContextIface, ConversationHandle, PersonHandle, PlaceRef, PrincipalRef, RouteDefinitionIface,
|
|
4
|
+
export type { AgentAvatarIface, AvatarMedia, AvatarState, AgentManifestIface, ChannelDefinitionIface, ChannelCredentialRef, ChannelCredentialHandle, ChannelCredentialsIface, ChannelCredentialSocketIface, ChannelReceiveContextIface, ChannelEventContextIface, ConversationHandle, PersonHandle, PlaceRef, PrincipalRef, RouteDefinitionIface, RoomPlatformIface, ChannelSocketIface, HarnessDescriptionIface, HarnessEndpointIface, HarnessIface, HarnessSessionRefIface, HostedBindingsIface, McpChannelIface, NetworkSandboxSessionIface, ResolvedAgentManifestIface, SandboxMcpEndpoint, SandboxPrepareContextIface, SandboxProcessIface, SandboxProviderHandleIface, SandboxProviderIface, SandboxProviderImplementationIface, SandboxSessionIface, SandboxStartContextIface, ScreenSessionIface, } from '@finalai/agent-provider';
|
|
5
5
|
export { requireHostedBinding } from '@finalai/agent-provider';
|
|
6
6
|
export { validateHostedBindings } from '@finalai/agent-definition';
|
|
7
7
|
export type { HostedBindingRequirementIface } from '@finalai/agent-provider';
|
|
8
8
|
export { defineFinalConnection } from '@finalai/final-agent-provider/connections';
|
|
9
9
|
export type { FinalConnectionDefinitionIface, FinalHostedConnectionDefinitionIface, } from '@finalai/final-agent-provider/connections';
|
|
10
|
+
export { bundleRef, ChannelCredentialKind, ChannelSigningAlgorithm, ChannelSignatureEncoding, ChannelOAuthClientAuthentication, } from "./authoring/index.mjs";
|
package/dist/modules/public.mjs
CHANGED
|
@@ -13,9 +13,7 @@ import {
|
|
|
13
13
|
credentials,
|
|
14
14
|
defineAgent,
|
|
15
15
|
defineChannel,
|
|
16
|
-
defineRoomSurface,
|
|
17
16
|
disableChannel,
|
|
18
|
-
defineProviderChannel,
|
|
19
17
|
defineDynamic,
|
|
20
18
|
defineHarness,
|
|
21
19
|
defineHostedConnection,
|
|
@@ -36,7 +34,18 @@ export * from "./authoring/providers.mjs";
|
|
|
36
34
|
import { requireHostedBinding } from "@finalai/agent-provider";
|
|
37
35
|
import { validateHostedBindings } from "@finalai/agent-definition";
|
|
38
36
|
import { defineFinalConnection } from "@finalai/final-agent-provider/connections";
|
|
37
|
+
import {
|
|
38
|
+
bundleRef,
|
|
39
|
+
ChannelCredentialKind,
|
|
40
|
+
ChannelSigningAlgorithm,
|
|
41
|
+
ChannelSignatureEncoding,
|
|
42
|
+
ChannelOAuthClientAuthentication
|
|
43
|
+
} from "./authoring/index.mjs";
|
|
39
44
|
export {
|
|
45
|
+
ChannelCredentialKind,
|
|
46
|
+
ChannelOAuthClientAuthentication,
|
|
47
|
+
ChannelSignatureEncoding,
|
|
48
|
+
ChannelSigningAlgorithm,
|
|
40
49
|
CredentialOwner,
|
|
41
50
|
CredentialPayer,
|
|
42
51
|
DELETE,
|
|
@@ -48,6 +57,7 @@ export {
|
|
|
48
57
|
WS,
|
|
49
58
|
always,
|
|
50
59
|
baseTools,
|
|
60
|
+
bundleRef,
|
|
51
61
|
credentials,
|
|
52
62
|
defineAgent,
|
|
53
63
|
defineChannel,
|
|
@@ -58,8 +68,6 @@ export {
|
|
|
58
68
|
defineHostedConnection,
|
|
59
69
|
defineInstructions,
|
|
60
70
|
defineMcpClientConnection,
|
|
61
|
-
defineProviderChannel,
|
|
62
|
-
defineRoomSurface,
|
|
63
71
|
defineSandbox,
|
|
64
72
|
defineSandboxProvider,
|
|
65
73
|
defineSchedule,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/public.ts"],
|
|
4
|
-
"sourcesContent": ["// Agent authoring.\nexport {\n CredentialOwner,\n CredentialPayer,\n DELETE,\n GET,\n HookEvent,\n POST,\n PUT,\n SandboxWire,\n WS,\n always,\n baseTools,\n credentials,\n defineAgent,\n defineChannel,\n
|
|
5
|
-
"mappings": "AACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,
|
|
4
|
+
"sourcesContent": ["// Agent authoring.\nexport {\n CredentialOwner,\n CredentialPayer,\n DELETE,\n GET,\n HookEvent,\n POST,\n PUT,\n SandboxWire,\n WS,\n always,\n baseTools,\n credentials,\n defineAgent,\n defineChannel,\n disableChannel,\n defineDynamic,\n defineHarness,\n defineHostedConnection,\n defineHook,\n defineInstructions,\n defineMcpClientConnection,\n defineSandbox,\n defineSandboxProvider,\n defineSchedule,\n defineSkill,\n defineTool,\n harnessHost,\n never,\n toolResultFrom,\n whenInput,\n} from \"./authoring/index.mjs\";\nexport type {\n AgentDefinitionInputIface,\n AgentSessionInfoIface,\n ApprovalPolicyIface,\n AuthoredChannelDefinitionIface,\n AuthoredHarnessCloseContextIface,\n AuthoredHarnessDescriptionIface,\n AuthoredHarnessEndpointIface,\n AuthoredHarnessHealthIface,\n AuthoredHarnessIface,\n AuthoredHarnessOpenArgsIface,\n AuthoredHarnessRefContextIface,\n AuthoredHarnessResumeArgsIface,\n BaseToolsValueIface,\n ConversationInfoIface,\n CredentialNode,\n CredentialPolicyIface,\n DefinedAuthoredHarnessIface,\n DefinedToolIface,\n DynamicDefinitionIface,\n DynamicResolveContextIface,\n DynamicSentinelIface,\n FinalPlatformClientIface,\n HarnessHostIface,\n HookContextIface,\n HookDefinitionIface,\n HookEventIface,\n HostedConnectionDefinitionIface,\n McpClientConnectionDefinitionIface,\n SandboxSelectorContextIface,\n ScheduleInputIface,\n SkillDefinitionIface,\n ToolContextIface,\n ToolDefinitionIface,\n} from \"./authoring/index.mjs\";\nexport * from \"./authoring/providers.mjs\";\n\nexport type {\n AgentAvatarIface,\n AvatarMedia,\n AvatarState,\n AgentManifestIface,\n ChannelDefinitionIface,\n ChannelCredentialRef,\n ChannelCredentialHandle,\n ChannelCredentialsIface,\n ChannelCredentialSocketIface,\n ChannelReceiveContextIface,\n ChannelEventContextIface,\n ConversationHandle,\n PersonHandle,\n PlaceRef,\n PrincipalRef,\n RouteDefinitionIface,\n RoomPlatformIface,\n ChannelSocketIface,\n HarnessDescriptionIface,\n HarnessEndpointIface,\n HarnessIface,\n HarnessSessionRefIface,\n HostedBindingsIface,\n McpChannelIface,\n NetworkSandboxSessionIface,\n ResolvedAgentManifestIface,\n SandboxMcpEndpoint,\n SandboxPrepareContextIface,\n SandboxProcessIface,\n SandboxProviderHandleIface,\n SandboxProviderIface,\n SandboxProviderImplementationIface,\n SandboxSessionIface,\n SandboxStartContextIface,\n ScreenSessionIface,\n} from '@finalai/agent-provider';\n\nexport { requireHostedBinding } from '@finalai/agent-provider';\nexport { validateHostedBindings } from '@finalai/agent-definition';\nexport type { HostedBindingRequirementIface } from '@finalai/agent-provider';\n\nexport { defineFinalConnection } from '@finalai/final-agent-provider/connections';\nexport type {\n FinalConnectionDefinitionIface,\n FinalHostedConnectionDefinitionIface,\n} from '@finalai/final-agent-provider/connections';\n\nexport {\n bundleRef,\n ChannelCredentialKind,\n ChannelSigningAlgorithm,\n ChannelSignatureEncoding,\n ChannelOAuthClientAuthentication,\n} from \"./authoring/index.mjs\";\n"],
|
|
5
|
+
"mappings": "AACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAoCP,cAAc;AAwCd,SAAS,4BAA4B;AACrC,SAAS,8BAA8B;AAGvC,SAAS,6BAA6B;AAMtC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,2 +1,32 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { defineChannel } from '@finalai/agent-provider';
|
|
2
|
+
import { verifyGithubSignature } from './github-signature';
|
|
3
|
+
export default defineChannel({
|
|
4
|
+
name: 'release-events',
|
|
5
|
+
config: { secret: 'github-webhook-secret', signatureHeader: 'x-final-signature' },
|
|
6
|
+
credentials: { app: null, secrets: ['github-webhook-secret'] },
|
|
7
|
+
identity: { kind: 'none' },
|
|
8
|
+
places: { kinds: ['webhook'] },
|
|
9
|
+
receive: async () => ({ accepted: true }),
|
|
10
|
+
routes: [
|
|
11
|
+
{
|
|
12
|
+
method: 'POST',
|
|
13
|
+
path: '/webhook',
|
|
14
|
+
handler: async (ctx) => {
|
|
15
|
+
const body = await ctx.request.text();
|
|
16
|
+
const headers = new Headers(ctx.request.headers);
|
|
17
|
+
const signature = headers.get('x-final-signature');
|
|
18
|
+
if (signature != null) headers.set('x-hub-signature-256', signature);
|
|
19
|
+
if (
|
|
20
|
+
!(await verifyGithubSignature(
|
|
21
|
+
new Request(ctx.request.url, { headers }),
|
|
22
|
+
body,
|
|
23
|
+
await ctx.credentials.secret('github-webhook-secret'),
|
|
24
|
+
))
|
|
25
|
+
)
|
|
26
|
+
return new Response(null, { status: 401 });
|
|
27
|
+
await ctx.receive(JSON.parse(body));
|
|
28
|
+
return new Response(null, { status: 202 });
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@finalai/agents",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Agent authoring, client APIs, and CLI.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -105,10 +105,10 @@
|
|
|
105
105
|
},
|
|
106
106
|
"dependencies": {
|
|
107
107
|
"@agentclientprotocol/sdk": "1.8.0",
|
|
108
|
-
"@finalai/agent-definition": "0.
|
|
109
|
-
"@finalai/agent-protocol": "0.
|
|
110
|
-
"@finalai/agent-provider": "0.
|
|
111
|
-
"@finalai/final-agent-provider": "0.
|
|
108
|
+
"@finalai/agent-definition": "0.8.0",
|
|
109
|
+
"@finalai/agent-protocol": "0.8.0",
|
|
110
|
+
"@finalai/agent-provider": "0.9.0",
|
|
111
|
+
"@finalai/final-agent-provider": "0.10.0",
|
|
112
112
|
"@finalai/websockets": "0.1.7",
|
|
113
113
|
"ws": "^8.21.3",
|
|
114
114
|
"zod": "4.6.6"
|