@finalai/agents 0.11.0 → 0.13.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 +334 -245
- package/README.md +214 -29
- package/dist/modules/agent-client/agent-input.d.mts +24 -0
- package/dist/modules/agent-client/agent-input.mjs +46 -0
- package/dist/modules/agent-client/agent-input.mjs.map +7 -0
- package/dist/modules/agent-client/channels.d.mts +128 -16
- package/dist/modules/agent-client/channels.mjs +216 -33
- package/dist/modules/agent-client/channels.mjs.map +2 -2
- package/dist/modules/agent-client/client.d.mts +91 -21
- package/dist/modules/agent-client/client.mjs +79 -24
- package/dist/modules/agent-client/client.mjs.map +2 -2
- package/dist/modules/agent-client/config-options.mjs +1 -2
- package/dist/modules/agent-client/config-options.mjs.map +2 -2
- package/dist/modules/agent-client/conversation-resources.d.mts +102 -0
- package/dist/modules/agent-client/conversation-resources.mjs +178 -0
- package/dist/modules/agent-client/conversation-resources.mjs.map +7 -0
- package/dist/modules/agent-client/conversations.d.mts +120 -38
- package/dist/modules/agent-client/conversations.mjs +386 -71
- package/dist/modules/agent-client/conversations.mjs.map +2 -2
- package/dist/modules/agent-client/defaults.d.mts +8 -0
- package/dist/modules/agent-client/defaults.mjs +77 -0
- package/dist/modules/agent-client/defaults.mjs.map +7 -0
- package/dist/modules/agent-client/errors.d.mts +22 -2
- package/dist/modules/agent-client/errors.mjs +19 -0
- package/dist/modules/agent-client/errors.mjs.map +2 -2
- package/dist/modules/agent-client/events.d.mts +62 -0
- package/dist/modules/agent-client/events.mjs +107 -0
- package/dist/modules/agent-client/events.mjs.map +7 -0
- package/dist/modules/agent-client/harnesses.d.mts +66 -0
- package/dist/modules/agent-client/harnesses.mjs +156 -0
- package/dist/modules/agent-client/harnesses.mjs.map +7 -0
- package/dist/modules/agent-client/http.d.mts +2 -1
- package/dist/modules/agent-client/http.mjs +21 -2
- package/dist/modules/agent-client/http.mjs.map +2 -2
- package/dist/modules/agent-client/index.d.mts +21 -6
- package/dist/modules/agent-client/index.mjs +26 -0
- package/dist/modules/agent-client/index.mjs.map +2 -2
- package/dist/modules/agent-client/integrations.d.mts +40 -0
- package/dist/modules/agent-client/integrations.mjs +92 -0
- package/dist/modules/agent-client/integrations.mjs.map +7 -0
- package/dist/modules/agent-client/local-host-protocol.d.mts +156 -0
- package/dist/modules/agent-client/local-host-protocol.mjs +258 -0
- package/dist/modules/agent-client/local-host-protocol.mjs.map +7 -0
- package/dist/modules/agent-client/local-host.d.mts +56 -0
- package/dist/modules/agent-client/local-host.mjs +200 -0
- package/dist/modules/agent-client/local-host.mjs.map +7 -0
- package/dist/modules/agent-client/oauth-clients.d.mts +36 -0
- package/dist/modules/agent-client/oauth-clients.mjs +67 -0
- package/dist/modules/agent-client/oauth-clients.mjs.map +7 -0
- package/dist/modules/agent-client/project-agents.d.mts +54 -0
- package/dist/modules/agent-client/project-agents.mjs +111 -0
- package/dist/modules/agent-client/project-agents.mjs.map +7 -0
- package/dist/modules/agent-client/project.d.mts +48 -0
- package/dist/modules/agent-client/project.mjs +66 -0
- package/dist/modules/agent-client/project.mjs.map +7 -0
- package/dist/modules/agent-client/projects.d.mts +61 -0
- package/dist/modules/agent-client/projects.mjs +145 -0
- package/dist/modules/agent-client/projects.mjs.map +7 -0
- package/dist/modules/agent-client/provide.d.mts +41 -0
- package/dist/modules/agent-client/provide.mjs +90 -0
- package/dist/modules/agent-client/provide.mjs.map +7 -0
- package/dist/modules/agent-client/publishers.d.mts +57 -0
- package/dist/modules/agent-client/publishers.mjs +109 -0
- package/dist/modules/agent-client/publishers.mjs.map +7 -0
- package/dist/modules/agent-client/requirements.d.mts +60 -0
- package/dist/modules/agent-client/requirements.mjs +83 -0
- package/dist/modules/agent-client/requirements.mjs.map +7 -0
- package/dist/modules/agent-client/sandbox-providers.d.mts +34 -0
- package/dist/modules/agent-client/sandbox-providers.mjs +75 -0
- package/dist/modules/agent-client/sandbox-providers.mjs.map +7 -0
- package/dist/modules/agent-client/sandbox-uri.d.mts +1 -1
- package/dist/modules/agent-client/sandbox-uri.mjs +4 -4
- package/dist/modules/agent-client/sandbox-uri.mjs.map +1 -1
- package/dist/modules/agent-client/sandboxes.d.mts +72 -0
- package/dist/modules/agent-client/sandboxes.mjs +138 -0
- package/dist/modules/agent-client/sandboxes.mjs.map +7 -0
- package/dist/modules/agent-client/schedules.d.mts +9 -0
- package/dist/modules/agent-client/schedules.mjs +17 -0
- package/dist/modules/agent-client/schedules.mjs.map +7 -0
- package/dist/modules/agent-client/sessions.d.mts +46 -8
- package/dist/modules/agent-client/sessions.mjs +91 -29
- package/dist/modules/agent-client/sessions.mjs.map +2 -2
- package/dist/modules/agent-client/start.d.mts +101 -0
- package/dist/modules/agent-client/start.mjs +260 -0
- package/dist/modules/agent-client/start.mjs.map +7 -0
- package/dist/modules/agent-client/test-fakes.d.mts +1 -0
- package/dist/modules/agent-client/test-fakes.mjs +3 -1
- package/dist/modules/agent-client/test-fakes.mjs.map +2 -2
- package/dist/modules/cli/agent-module.d.mts +39 -0
- package/dist/modules/cli/agent-module.mjs +89 -0
- package/dist/modules/cli/agent-module.mjs.map +7 -0
- package/dist/modules/cli/cli.d.mts +6 -6
- package/dist/modules/cli/cli.mjs +94 -120
- package/dist/modules/cli/cli.mjs.map +2 -2
- package/dist/modules/cli/conformance.d.mts +2 -6
- package/dist/modules/cli/conformance.mjs +5 -8
- package/dist/modules/cli/conformance.mjs.map +2 -2
- package/dist/modules/cli/main.mjs.map +1 -1
- package/dist/modules/cli/output.d.mts +0 -9
- package/dist/modules/cli/output.mjs +7 -85
- package/dist/modules/cli/output.mjs.map +2 -2
- package/dist/modules/harnesses.mjs.map +2 -2
- package/dist/modules/index.d.mts +0 -2
- package/dist/modules/index.mjs +0 -4
- package/dist/modules/index.mjs.map +2 -2
- package/dist/modules/integrations.d.mts +24 -0
- package/dist/modules/integrations.mjs +30 -0
- package/dist/modules/integrations.mjs.map +7 -0
- package/dist/modules/public.d.mts +10 -10
- package/dist/modules/public.mjs +29 -78
- package/dist/modules/public.mjs.map +2 -2
- package/dist/modules/sandboxes.d.mts +2 -0
- package/dist/modules/sandboxes.mjs +4 -0
- package/dist/modules/sandboxes.mjs.map +2 -2
- package/dist/modules/verify.d.mts +1 -0
- package/dist/modules/verify.mjs +2 -0
- package/dist/modules/verify.mjs.map +7 -0
- package/dist/modules/webhooks.d.mts +37 -0
- package/dist/modules/webhooks.mjs +100 -0
- package/dist/modules/webhooks.mjs.map +7 -0
- package/examples/release-scout/README.md +18 -10
- package/examples/release-scout/agent.ts +41 -0
- package/examples/release-scout/by-name.ts +43 -0
- package/examples/release-scout/db.ts +6 -0
- package/examples/release-scout/instructions.md +5 -0
- package/examples/release-scout/run-on-a-computer.ts +49 -0
- package/examples/release-scout/run.ts +38 -0
- package/package.json +37 -28
- package/dist/modules/agent-client/build.d.mts +0 -110
- package/dist/modules/agent-client/build.mjs +0 -213
- package/dist/modules/agent-client/build.mjs.map +0 -7
- package/dist/modules/authoring/final-channel.d.mts +0 -1
- package/dist/modules/authoring/final-channel.mjs +0 -2
- package/dist/modules/authoring/final-channel.mjs.map +0 -7
- package/dist/modules/authoring/index.d.mts +0 -1
- package/dist/modules/authoring/index.mjs +0 -2
- package/dist/modules/authoring/index.mjs.map +0 -7
- package/dist/modules/authoring/instructions.d.mts +0 -1
- package/dist/modules/authoring/instructions.mjs +0 -2
- package/dist/modules/authoring/instructions.mjs.map +0 -7
- package/dist/modules/authoring/providers.d.mts +0 -2
- package/dist/modules/authoring/providers.mjs +0 -1
- package/dist/modules/authoring/providers.mjs.map +0 -7
- package/dist/modules/cli/build.d.mts +0 -22
- package/dist/modules/cli/build.mjs +0 -77
- package/dist/modules/cli/build.mjs.map +0 -7
- package/dist/modules/cli/channel-install.d.mts +0 -12
- package/dist/modules/cli/channel-install.mjs +0 -25
- package/dist/modules/cli/channel-install.mjs.map +0 -7
- package/dist/modules/cli/channel-socket.d.mts +0 -9
- package/dist/modules/cli/channel-socket.mjs +0 -114
- package/dist/modules/cli/channel-socket.mjs.map +0 -7
- package/dist/modules/cli/dev.d.mts +0 -26
- package/dist/modules/cli/dev.mjs +0 -311
- package/dist/modules/cli/dev.mjs.map +0 -7
- package/dist/modules/cli/files.d.mts +0 -18
- package/dist/modules/cli/files.mjs +0 -66
- package/dist/modules/cli/files.mjs.map +0 -7
- package/dist/modules/cli/harness-descriptions.d.mts +0 -20
- package/dist/modules/cli/harness-descriptions.mjs +0 -70
- package/dist/modules/cli/harness-descriptions.mjs.map +0 -7
- package/dist/modules/cli/publish.d.mts +0 -15
- package/dist/modules/cli/publish.mjs +0 -92
- package/dist/modules/cli/publish.mjs.map +0 -7
- package/dist/modules/compile.d.mts +0 -3
- package/dist/modules/compile.mjs +0 -58
- package/dist/modules/compile.mjs.map +0 -7
- package/dist/modules/index.browser.d.mts +0 -4
- package/dist/modules/index.browser.mjs +0 -8
- package/dist/modules/index.browser.mjs.map +0 -7
- package/examples/custom-harness/README.md +0 -16
- package/examples/custom-harness/agent.ts +0 -154
- package/examples/custom-sandbox/README.md +0 -12
- package/examples/custom-sandbox/agent.ts +0 -14
- package/examples/custom-sandbox/sandbox.ts +0 -24
- package/examples/release-scout/agent/agent.ts +0 -22
- package/examples/release-scout/agent/channels/github-signature.ts +0 -27
- package/examples/release-scout/agent/channels/github.ts +0 -32
- package/examples/release-scout/agent/connections/linear.ts +0 -9
- package/examples/release-scout/agent/hooks/audit.ts +0 -24
- package/examples/release-scout/agent/instructions/org-context.ts +0 -26
- package/examples/release-scout/agent/instructions.md +0 -2
- package/examples/release-scout/agent/sandbox.ts +0 -20
- package/examples/release-scout/agent/schedules/daily-digest.md +0 -7
- package/examples/release-scout/agent/skills/triage/SKILL.md +0 -8
- package/examples/release-scout/agent/skills/triage/checklist.md +0 -3
- package/examples/release-scout/agent/tools/lookup_release_notes.ts +0 -24
- package/examples/release-scout/client.ts +0 -122
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { Capability } from '@finalai/agent-protocol';
|
|
2
|
+
import { jsonValueSchema } from '@finalai/agent-provider/json';
|
|
3
|
+
import { CodeLineType } from '@finalai/agent-provider/code-host';
|
|
4
|
+
import type { FrameChannelIface, WireFrame } from '@finalai/agent-provider/sandbox/wire';
|
|
5
|
+
import * as z from 'zod';
|
|
6
|
+
export declare const LOCAL_HOST_PROTOCOL_VERSION = 1;
|
|
7
|
+
export declare const LOCAL_HOST_SUBPROTOCOL = "final.local-host.v1";
|
|
8
|
+
export declare const LOCAL_HOST_REQUEST_ID_PREFIX = "host:";
|
|
9
|
+
export declare const localHostPath: (projectId: string) => string;
|
|
10
|
+
export declare enum LocalHostMethod {
|
|
11
|
+
Hello = "host/hello",
|
|
12
|
+
CodeRun = "code/run",
|
|
13
|
+
CodeProgress = "code/progress",
|
|
14
|
+
CodeSecret = "code/secret"
|
|
15
|
+
}
|
|
16
|
+
export declare const CANCEL_REQUEST_METHOD = "$/cancel_request";
|
|
17
|
+
export declare enum LocalHostOwnerKind {
|
|
18
|
+
Session = "session",
|
|
19
|
+
Conversation = "conversation"
|
|
20
|
+
}
|
|
21
|
+
export declare const localHostOwnerSchema: z.ZodObject<{
|
|
22
|
+
kind: z.ZodEnum<typeof LocalHostOwnerKind>;
|
|
23
|
+
id: z.ZodOptional<z.ZodString>;
|
|
24
|
+
}, z.core.$strict>;
|
|
25
|
+
export type LocalHostOwnerIface = z.input<typeof localHostOwnerSchema>;
|
|
26
|
+
export declare const localHostHelloParamsSchema: z.ZodObject<{
|
|
27
|
+
protocolVersion: z.ZodLiteral<1>;
|
|
28
|
+
owner: z.ZodObject<{
|
|
29
|
+
kind: z.ZodEnum<typeof LocalHostOwnerKind>;
|
|
30
|
+
id: z.ZodOptional<z.ZodString>;
|
|
31
|
+
}, z.core.$strict>;
|
|
32
|
+
agent: z.ZodString;
|
|
33
|
+
capabilities: z.ZodArray<z.ZodEnum<typeof Capability>>;
|
|
34
|
+
tools: z.ZodArray<z.ZodString>;
|
|
35
|
+
hooks: z.ZodArray<z.ZodString>;
|
|
36
|
+
approvals: z.ZodArray<z.ZodString>;
|
|
37
|
+
resume: z.ZodOptional<z.ZodString>;
|
|
38
|
+
}, z.core.$strict>;
|
|
39
|
+
export type LocalHostHelloParamsIface = z.input<typeof localHostHelloParamsSchema>;
|
|
40
|
+
export declare const localHostHelloResultSchema: z.ZodObject<{
|
|
41
|
+
hostId: z.ZodString;
|
|
42
|
+
owner: z.ZodObject<{
|
|
43
|
+
kind: z.ZodString;
|
|
44
|
+
id: z.ZodString;
|
|
45
|
+
}, z.core.$strip>;
|
|
46
|
+
sandboxId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
47
|
+
}, z.core.$strip>;
|
|
48
|
+
export type LocalHostHelloResultIface = z.infer<typeof localHostHelloResultSchema>;
|
|
49
|
+
export declare const localHostCodeRunParamsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
50
|
+
kind: z.ZodLiteral<import("@finalai/agent-provider").CodeKind.Tool>;
|
|
51
|
+
name: z.ZodString;
|
|
52
|
+
input: z.ZodType<import("@finalai/agent-provider").JsonValue, unknown, z.core.$ZodTypeInternals<import("@finalai/agent-provider").JsonValue, unknown>>;
|
|
53
|
+
context: z.ZodObject<{
|
|
54
|
+
sessionId: z.ZodNullable<z.ZodString>;
|
|
55
|
+
callId: z.ZodString;
|
|
56
|
+
actingUserId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
57
|
+
compute: z.ZodDefault<z.ZodRecord<z.ZodEnum<typeof Capability> & z.core.$partial, z.ZodObject<{
|
|
58
|
+
url: z.ZodString;
|
|
59
|
+
token: z.ZodString;
|
|
60
|
+
expiresAt: z.ZodString;
|
|
61
|
+
}, z.core.$strip>>>;
|
|
62
|
+
}, z.core.$strip>;
|
|
63
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
64
|
+
kind: z.ZodLiteral<import("@finalai/agent-provider").CodeKind.Hook>;
|
|
65
|
+
name: z.ZodString;
|
|
66
|
+
event: z.ZodString;
|
|
67
|
+
payload: z.ZodType<import("@finalai/agent-provider").JsonValue, unknown, z.core.$ZodTypeInternals<import("@finalai/agent-provider").JsonValue, unknown>>;
|
|
68
|
+
context: z.ZodObject<{
|
|
69
|
+
sessionId: z.ZodNullable<z.ZodString>;
|
|
70
|
+
callId: z.ZodString;
|
|
71
|
+
actingUserId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
72
|
+
compute: z.ZodDefault<z.ZodRecord<z.ZodEnum<typeof Capability> & z.core.$partial, z.ZodObject<{
|
|
73
|
+
url: z.ZodString;
|
|
74
|
+
token: z.ZodString;
|
|
75
|
+
expiresAt: z.ZodString;
|
|
76
|
+
}, z.core.$strip>>>;
|
|
77
|
+
}, z.core.$strip>;
|
|
78
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
79
|
+
kind: z.ZodLiteral<import("@finalai/agent-provider").CodeKind.Approval>;
|
|
80
|
+
name: z.ZodString;
|
|
81
|
+
input: z.ZodType<import("@finalai/agent-provider").JsonValue, unknown, z.core.$ZodTypeInternals<import("@finalai/agent-provider").JsonValue, unknown>>;
|
|
82
|
+
context: z.ZodObject<{
|
|
83
|
+
sessionId: z.ZodNullable<z.ZodString>;
|
|
84
|
+
callId: z.ZodString;
|
|
85
|
+
actingUserId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
86
|
+
compute: z.ZodDefault<z.ZodRecord<z.ZodEnum<typeof Capability> & z.core.$partial, z.ZodObject<{
|
|
87
|
+
url: z.ZodString;
|
|
88
|
+
token: z.ZodString;
|
|
89
|
+
expiresAt: z.ZodString;
|
|
90
|
+
}, z.core.$strip>>>;
|
|
91
|
+
}, z.core.$strip>;
|
|
92
|
+
}, z.core.$strip>], "kind">;
|
|
93
|
+
export declare const localHostCodeProgressParamsSchema: z.ZodObject<{
|
|
94
|
+
requestId: z.ZodString;
|
|
95
|
+
data: z.ZodType<import("@finalai/agent-provider").JsonValue, unknown, z.core.$ZodTypeInternals<import("@finalai/agent-provider").JsonValue, unknown>>;
|
|
96
|
+
label: z.ZodOptional<z.ZodString>;
|
|
97
|
+
}, z.core.$strict>;
|
|
98
|
+
export declare const localHostSecretParamsSchema: z.ZodObject<{
|
|
99
|
+
requestId: z.ZodString;
|
|
100
|
+
name: z.ZodString;
|
|
101
|
+
}, z.core.$strict>;
|
|
102
|
+
export declare const localHostSecretResultSchema: z.ZodObject<{
|
|
103
|
+
value: z.ZodNullable<z.ZodString>;
|
|
104
|
+
}, z.core.$strip>;
|
|
105
|
+
export declare const localHostCodeResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
106
|
+
type: z.ZodLiteral<CodeLineType.Result>;
|
|
107
|
+
output: z.ZodType<import("@finalai/agent-provider").JsonValue, unknown, z.core.$ZodTypeInternals<import("@finalai/agent-provider").JsonValue, unknown>>;
|
|
108
|
+
modelOutput: z.ZodOptional<z.ZodType<import("@finalai/agent-provider").JsonValue, unknown, z.core.$ZodTypeInternals<import("@finalai/agent-provider").JsonValue, unknown>>>;
|
|
109
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
110
|
+
type: z.ZodLiteral<CodeLineType.Error>;
|
|
111
|
+
message: z.ZodString;
|
|
112
|
+
}, z.core.$strip>], "type">;
|
|
113
|
+
export type LocalHostCodeResultIface = z.infer<typeof localHostCodeResultSchema>;
|
|
114
|
+
/** Whether a frame on the shared socket belongs to the host protocol. */
|
|
115
|
+
export declare const isHostFrame: (frame: WireFrame) => boolean;
|
|
116
|
+
export interface LocalHostChannelsIface {
|
|
117
|
+
sandbox: FrameChannelIface;
|
|
118
|
+
host: FrameChannelIface;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Splits the shared socket into the sandbox wire and the host protocol. Both
|
|
122
|
+
* sides of the connection use it; closing either closes the socket.
|
|
123
|
+
*/
|
|
124
|
+
export declare const splitLocalHostChannel: (socket: FrameChannelIface) => LocalHostChannelsIface;
|
|
125
|
+
export interface HostRequestContextIface {
|
|
126
|
+
id: string;
|
|
127
|
+
params: z.output<typeof jsonValueSchema> | undefined;
|
|
128
|
+
signal: AbortSignal;
|
|
129
|
+
}
|
|
130
|
+
export interface HostPeerIface {
|
|
131
|
+
request: (method: string, params: z.input<typeof jsonValueSchema>) => Promise<unknown>;
|
|
132
|
+
notify: (method: string, params: z.input<typeof jsonValueSchema>) => void;
|
|
133
|
+
close: (code?: number, reason?: string) => void;
|
|
134
|
+
/** Resolves when the socket closes, for any reason. */
|
|
135
|
+
closed: Promise<{
|
|
136
|
+
code: number;
|
|
137
|
+
reason: string;
|
|
138
|
+
}>;
|
|
139
|
+
isClosed: () => boolean;
|
|
140
|
+
}
|
|
141
|
+
export declare enum HostRpcErrorCode {
|
|
142
|
+
MethodNotFound = -32601,
|
|
143
|
+
InvalidParams = -32602,
|
|
144
|
+
Internal = -32603,
|
|
145
|
+
Cancelled = -32800
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* JSON-RPC 2.0 for the host protocol. Ids it sends are strings starting with
|
|
149
|
+
* `host:`, so the far side routes their responses (see `isHostFrame`).
|
|
150
|
+
*/
|
|
151
|
+
export declare const createHostPeer: (args: {
|
|
152
|
+
channel: FrameChannelIface;
|
|
153
|
+
onRequest?: (method: string, context: HostRequestContextIface) => Promise<unknown>;
|
|
154
|
+
onNotification?: (method: string, params: z.output<typeof jsonValueSchema> | undefined) => void;
|
|
155
|
+
newId?: () => string;
|
|
156
|
+
}) => HostPeerIface;
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import { Capability } from "@finalai/agent-protocol";
|
|
2
|
+
import { jsonValueSchema } from "@finalai/agent-provider/json";
|
|
3
|
+
import { codeInvocationSchema, CodeLineType } from "@finalai/agent-provider/code-host";
|
|
4
|
+
import * as z from "zod";
|
|
5
|
+
const LOCAL_HOST_PROTOCOL_VERSION = 1;
|
|
6
|
+
const LOCAL_HOST_SUBPROTOCOL = "final.local-host.v1";
|
|
7
|
+
const LOCAL_HOST_REQUEST_ID_PREFIX = "host:";
|
|
8
|
+
const localHostPath = (projectId) => `/v1/projects/${encodeURIComponent(projectId)}/local-hosts`;
|
|
9
|
+
var LocalHostMethod = /* @__PURE__ */ ((LocalHostMethod2) => {
|
|
10
|
+
LocalHostMethod2["Hello"] = "host/hello";
|
|
11
|
+
LocalHostMethod2["CodeRun"] = "code/run";
|
|
12
|
+
LocalHostMethod2["CodeProgress"] = "code/progress";
|
|
13
|
+
LocalHostMethod2["CodeSecret"] = "code/secret";
|
|
14
|
+
return LocalHostMethod2;
|
|
15
|
+
})(LocalHostMethod || {});
|
|
16
|
+
const CANCEL_REQUEST_METHOD = "$/cancel_request";
|
|
17
|
+
var LocalHostOwnerKind = /* @__PURE__ */ ((LocalHostOwnerKind2) => {
|
|
18
|
+
LocalHostOwnerKind2["Session"] = "session";
|
|
19
|
+
LocalHostOwnerKind2["Conversation"] = "conversation";
|
|
20
|
+
return LocalHostOwnerKind2;
|
|
21
|
+
})(LocalHostOwnerKind || {});
|
|
22
|
+
const localHostOwnerSchema = z.strictObject({
|
|
23
|
+
kind: z.nativeEnum(LocalHostOwnerKind),
|
|
24
|
+
// Absent: the platform reserves a new id the client then creates with.
|
|
25
|
+
id: z.string().min(1).max(200).optional()
|
|
26
|
+
});
|
|
27
|
+
const localHostHelloParamsSchema = z.strictObject({
|
|
28
|
+
protocolVersion: z.literal(LOCAL_HOST_PROTOCOL_VERSION),
|
|
29
|
+
// The session or conversation the agent runs in.
|
|
30
|
+
owner: localHostOwnerSchema,
|
|
31
|
+
// The agent's content hash; its document is stored before or with the create call.
|
|
32
|
+
agent: z.string().min(1),
|
|
33
|
+
// Capabilities served from this process; empty when it only answers code.
|
|
34
|
+
capabilities: z.array(z.nativeEnum(Capability)),
|
|
35
|
+
// In-process code this process answers, by its name in the document.
|
|
36
|
+
tools: z.array(z.string()),
|
|
37
|
+
hooks: z.array(z.string()),
|
|
38
|
+
approvals: z.array(z.string()),
|
|
39
|
+
// A host id from an earlier connection, to resume after a disconnect.
|
|
40
|
+
resume: z.string().min(1).optional()
|
|
41
|
+
});
|
|
42
|
+
const localHostHelloResultSchema = z.object({
|
|
43
|
+
hostId: z.string(),
|
|
44
|
+
owner: z.object({ kind: z.string(), id: z.string() }),
|
|
45
|
+
// The sandbox id that names this process's compute in `provide.compute`;
|
|
46
|
+
// null when no capability is served.
|
|
47
|
+
sandboxId: z.string().nullable().default(null)
|
|
48
|
+
});
|
|
49
|
+
const localHostCodeRunParamsSchema = codeInvocationSchema;
|
|
50
|
+
const localHostCodeProgressParamsSchema = z.strictObject({
|
|
51
|
+
requestId: z.string(),
|
|
52
|
+
data: jsonValueSchema,
|
|
53
|
+
label: z.string().optional()
|
|
54
|
+
});
|
|
55
|
+
const localHostSecretParamsSchema = z.strictObject({
|
|
56
|
+
requestId: z.string(),
|
|
57
|
+
name: z.string().min(1)
|
|
58
|
+
});
|
|
59
|
+
const localHostSecretResultSchema = z.object({
|
|
60
|
+
// Null when the project has no such secret set.
|
|
61
|
+
value: z.string().nullable()
|
|
62
|
+
});
|
|
63
|
+
const localHostCodeResultSchema = z.discriminatedUnion("type", [
|
|
64
|
+
z.object({
|
|
65
|
+
type: z.literal(CodeLineType.Result),
|
|
66
|
+
output: jsonValueSchema,
|
|
67
|
+
modelOutput: jsonValueSchema.optional()
|
|
68
|
+
}),
|
|
69
|
+
z.object({ type: z.literal(CodeLineType.Error), message: z.string() })
|
|
70
|
+
]);
|
|
71
|
+
const textFrameSchema = z.looseObject({
|
|
72
|
+
method: z.string().optional(),
|
|
73
|
+
id: z.union([z.string(), z.number(), z.null()]).optional(),
|
|
74
|
+
params: z.looseObject({ requestId: z.union([z.string(), z.number()]).optional() }).optional()
|
|
75
|
+
});
|
|
76
|
+
const isHostId = (id) => typeof id === "string" && id.startsWith(LOCAL_HOST_REQUEST_ID_PREFIX);
|
|
77
|
+
const isHostFrame = (frame) => {
|
|
78
|
+
if (typeof frame !== "string") return false;
|
|
79
|
+
let raw;
|
|
80
|
+
try {
|
|
81
|
+
raw = JSON.parse(frame);
|
|
82
|
+
} catch {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
const message = textFrameSchema.safeParse(raw);
|
|
86
|
+
if (!message.success) return false;
|
|
87
|
+
const method = message.data.method;
|
|
88
|
+
if (method === CANCEL_REQUEST_METHOD) return isHostId(message.data.params?.requestId);
|
|
89
|
+
if (method != null) return method.startsWith("host/") || method.startsWith("code/");
|
|
90
|
+
return isHostId(message.data.id);
|
|
91
|
+
};
|
|
92
|
+
const splitLocalHostChannel = (socket) => {
|
|
93
|
+
const make = () => {
|
|
94
|
+
let handlers = null;
|
|
95
|
+
const pending = [];
|
|
96
|
+
let closed = null;
|
|
97
|
+
const channel = {
|
|
98
|
+
send: (frame) => socket.send(frame),
|
|
99
|
+
close: (code, reason) => socket.close(code, reason),
|
|
100
|
+
listen: (next) => {
|
|
101
|
+
handlers = next;
|
|
102
|
+
for (const frame of pending.splice(0)) next.frame(frame);
|
|
103
|
+
if (closed != null) next.close(closed);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
return {
|
|
107
|
+
channel,
|
|
108
|
+
frame: (frame) => {
|
|
109
|
+
if (handlers == null) pending.push(frame);
|
|
110
|
+
else handlers.frame(frame);
|
|
111
|
+
},
|
|
112
|
+
close: (info) => {
|
|
113
|
+
if (closed != null) return;
|
|
114
|
+
closed = info;
|
|
115
|
+
handlers?.close(info);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
const sandbox = make();
|
|
120
|
+
const host = make();
|
|
121
|
+
socket.listen({
|
|
122
|
+
frame: (frame) => (isHostFrame(frame) ? host : sandbox).frame(frame),
|
|
123
|
+
close: (info) => {
|
|
124
|
+
sandbox.close(info);
|
|
125
|
+
host.close(info);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
return { sandbox: sandbox.channel, host: host.channel };
|
|
129
|
+
};
|
|
130
|
+
const hostMessageSchema = z.looseObject({
|
|
131
|
+
method: z.string().optional(),
|
|
132
|
+
id: z.union([z.string(), z.number(), z.null()]).optional(),
|
|
133
|
+
params: jsonValueSchema.optional(),
|
|
134
|
+
result: jsonValueSchema.optional(),
|
|
135
|
+
error: z.looseObject({ code: z.number(), message: z.string() }).optional()
|
|
136
|
+
});
|
|
137
|
+
const cancelParamsSchema = z.object({ requestId: z.string() });
|
|
138
|
+
var HostRpcErrorCode = /* @__PURE__ */ ((HostRpcErrorCode2) => {
|
|
139
|
+
HostRpcErrorCode2[HostRpcErrorCode2["MethodNotFound"] = -32601] = "MethodNotFound";
|
|
140
|
+
HostRpcErrorCode2[HostRpcErrorCode2["InvalidParams"] = -32602] = "InvalidParams";
|
|
141
|
+
HostRpcErrorCode2[HostRpcErrorCode2["Internal"] = -32603] = "Internal";
|
|
142
|
+
HostRpcErrorCode2[HostRpcErrorCode2["Cancelled"] = -32800] = "Cancelled";
|
|
143
|
+
return HostRpcErrorCode2;
|
|
144
|
+
})(HostRpcErrorCode || {});
|
|
145
|
+
const createHostPeer = (args) => {
|
|
146
|
+
let counter = 0;
|
|
147
|
+
const newId = args.newId ?? (() => `${LOCAL_HOST_REQUEST_ID_PREFIX}${++counter}`);
|
|
148
|
+
const pending = /* @__PURE__ */ new Map();
|
|
149
|
+
const inbound = /* @__PURE__ */ new Map();
|
|
150
|
+
let closedInfo = null;
|
|
151
|
+
let resolveClosed = () => void 0;
|
|
152
|
+
const closed = new Promise((resolve) => {
|
|
153
|
+
resolveClosed = resolve;
|
|
154
|
+
});
|
|
155
|
+
const send = (message) => {
|
|
156
|
+
if (closedInfo == null) args.channel.send(JSON.stringify({ jsonrpc: "2.0", ...message }));
|
|
157
|
+
};
|
|
158
|
+
const answer = async (method, id, params) => {
|
|
159
|
+
const controller = new AbortController();
|
|
160
|
+
inbound.set(id, controller);
|
|
161
|
+
try {
|
|
162
|
+
const handler = args.onRequest;
|
|
163
|
+
if (handler == null) {
|
|
164
|
+
send({ id, error: { code: -32601 /* MethodNotFound */, message: method } });
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const result = await handler(method, { id, params, signal: controller.signal });
|
|
168
|
+
send(
|
|
169
|
+
controller.signal.aborted ? { id, error: { code: -32800 /* Cancelled */, message: "request cancelled" } } : { id, result: result ?? {} }
|
|
170
|
+
);
|
|
171
|
+
} catch (cause) {
|
|
172
|
+
send({
|
|
173
|
+
id,
|
|
174
|
+
error: {
|
|
175
|
+
code: -32603 /* Internal */,
|
|
176
|
+
message: cause instanceof Error ? cause.message : String(cause)
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
} finally {
|
|
180
|
+
inbound.delete(id);
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
args.channel.listen({
|
|
184
|
+
frame: (frame) => {
|
|
185
|
+
if (typeof frame !== "string") return;
|
|
186
|
+
let raw;
|
|
187
|
+
try {
|
|
188
|
+
raw = JSON.parse(frame);
|
|
189
|
+
} catch {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const message = hostMessageSchema.safeParse(raw);
|
|
193
|
+
if (!message.success) return;
|
|
194
|
+
const { method, id } = message.data;
|
|
195
|
+
if (method === CANCEL_REQUEST_METHOD) {
|
|
196
|
+
const cancel = cancelParamsSchema.safeParse(message.data.params);
|
|
197
|
+
if (cancel.success) inbound.get(cancel.data.requestId)?.abort();
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
if (method != null) {
|
|
201
|
+
if (id == null) args.onNotification?.(method, message.data.params);
|
|
202
|
+
else void answer(method, String(id), message.data.params);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
if (typeof id !== "string") return;
|
|
206
|
+
const waiter = pending.get(id);
|
|
207
|
+
if (waiter == null) return;
|
|
208
|
+
pending.delete(id);
|
|
209
|
+
if (message.data.error != null) waiter.reject(new Error(message.data.error.message));
|
|
210
|
+
else waiter.resolve(message.data.result ?? null);
|
|
211
|
+
},
|
|
212
|
+
close: (info) => {
|
|
213
|
+
if (closedInfo != null) return;
|
|
214
|
+
closedInfo = info;
|
|
215
|
+
for (const controller of inbound.values()) controller.abort();
|
|
216
|
+
for (const waiter of pending.values())
|
|
217
|
+
waiter.reject(new Error(`local host connection closed (${info.code})`));
|
|
218
|
+
pending.clear();
|
|
219
|
+
resolveClosed(info);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
return {
|
|
223
|
+
request: (method, params) => {
|
|
224
|
+
if (closedInfo != null) return Promise.reject(new Error("local host connection is closed"));
|
|
225
|
+
const id = newId();
|
|
226
|
+
return new Promise((resolve, reject) => {
|
|
227
|
+
pending.set(id, { resolve, reject });
|
|
228
|
+
send({ id, method, params });
|
|
229
|
+
});
|
|
230
|
+
},
|
|
231
|
+
notify: (method, params) => send({ method, params }),
|
|
232
|
+
close: (code, reason) => args.channel.close(code, reason),
|
|
233
|
+
closed,
|
|
234
|
+
isClosed: () => closedInfo != null
|
|
235
|
+
};
|
|
236
|
+
};
|
|
237
|
+
export {
|
|
238
|
+
CANCEL_REQUEST_METHOD,
|
|
239
|
+
HostRpcErrorCode,
|
|
240
|
+
LOCAL_HOST_PROTOCOL_VERSION,
|
|
241
|
+
LOCAL_HOST_REQUEST_ID_PREFIX,
|
|
242
|
+
LOCAL_HOST_SUBPROTOCOL,
|
|
243
|
+
LocalHostMethod,
|
|
244
|
+
LocalHostOwnerKind,
|
|
245
|
+
createHostPeer,
|
|
246
|
+
isHostFrame,
|
|
247
|
+
localHostCodeProgressParamsSchema,
|
|
248
|
+
localHostCodeResultSchema,
|
|
249
|
+
localHostCodeRunParamsSchema,
|
|
250
|
+
localHostHelloParamsSchema,
|
|
251
|
+
localHostHelloResultSchema,
|
|
252
|
+
localHostOwnerSchema,
|
|
253
|
+
localHostPath,
|
|
254
|
+
localHostSecretParamsSchema,
|
|
255
|
+
localHostSecretResultSchema,
|
|
256
|
+
splitLocalHostChannel
|
|
257
|
+
};
|
|
258
|
+
//# sourceMappingURL=local-host-protocol.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/agent-client/local-host-protocol.ts"],
|
|
4
|
+
"sourcesContent": ["import { Capability } from '@finalai/agent-protocol';\nimport { jsonValueSchema } from '@finalai/agent-provider/json';\nimport { codeInvocationSchema, CodeLineType } from '@finalai/agent-provider/code-host';\nimport type { FrameChannelIface, WireFrame } from '@finalai/agent-provider/sandbox/wire';\nimport * as z from 'zod';\n\n// The connection a client dials so the platform can use its process: a\n// WebSocket to `/api/v1/projects/:projectId/local-hosts`, one per agent it\n// started. On it the client serves the agent's `files` and `shell` with the\n// sandbox handle RPC (`@finalai/agent-provider/sandbox/wire`, the platform\n// being the RPC client) and answers calls to the agent's in-process tools,\n// hooks and approval predicates with the small JSON-RPC below. HOSTING.md\n// documents both directions.\n//\n// Both kinds of message share one socket. Binary frames are always the\n// sandbox wire's stream chunks. A text frame belongs to the host protocol when\n// it is a request or notification whose method starts with `host/` or `code/`,\n// or a response (or `$/cancel_request`) whose id is a string starting with\n// `host:`; every other frame is the sandbox wire's, whose ids are numbers.\n\nexport const LOCAL_HOST_PROTOCOL_VERSION = 1;\nexport const LOCAL_HOST_SUBPROTOCOL = 'final.local-host.v1';\nexport const LOCAL_HOST_REQUEST_ID_PREFIX = 'host:';\n\nexport const localHostPath = (projectId: string): string =>\n `/v1/projects/${encodeURIComponent(projectId)}/local-hosts`;\n\nexport enum LocalHostMethod {\n // Client \u2192 platform, first on every connection.\n Hello = 'host/hello',\n // Platform \u2192 client: run one in-process tool, hook or approval predicate.\n CodeRun = 'code/run',\n // Client \u2192 platform notification: progress of a running `code/run`.\n CodeProgress = 'code/progress',\n // Client \u2192 platform: a project secret for a running `code/run`.\n CodeSecret = 'code/secret',\n}\n\nexport const CANCEL_REQUEST_METHOD = '$/cancel_request';\n\nexport enum LocalHostOwnerKind {\n Session = 'session',\n Conversation = 'conversation',\n}\n\nexport const localHostOwnerSchema = z.strictObject({\n kind: z.nativeEnum(LocalHostOwnerKind),\n // Absent: the platform reserves a new id the client then creates with.\n id: z.string().min(1).max(200).optional(),\n});\n\nexport type LocalHostOwnerIface = z.input<typeof localHostOwnerSchema>;\n\nexport const localHostHelloParamsSchema = z.strictObject({\n protocolVersion: z.literal(LOCAL_HOST_PROTOCOL_VERSION),\n // The session or conversation the agent runs in.\n owner: localHostOwnerSchema,\n // The agent's content hash; its document is stored before or with the create call.\n agent: z.string().min(1),\n // Capabilities served from this process; empty when it only answers code.\n capabilities: z.array(z.nativeEnum(Capability)),\n // In-process code this process answers, by its name in the document.\n tools: z.array(z.string()),\n hooks: z.array(z.string()),\n approvals: z.array(z.string()),\n // A host id from an earlier connection, to resume after a disconnect.\n resume: z.string().min(1).optional(),\n});\n\nexport type LocalHostHelloParamsIface = z.input<typeof localHostHelloParamsSchema>;\n\nexport const localHostHelloResultSchema = z.object({\n hostId: z.string(),\n owner: z.object({ kind: z.string(), id: z.string() }),\n // The sandbox id that names this process's compute in `provide.compute`;\n // null when no capability is served.\n sandboxId: z.string().nullable().default(null),\n});\n\nexport type LocalHostHelloResultIface = z.infer<typeof localHostHelloResultSchema>;\n\nexport const localHostCodeRunParamsSchema = codeInvocationSchema;\n\nexport const localHostCodeProgressParamsSchema = z.strictObject({\n requestId: z.string(),\n data: jsonValueSchema,\n label: z.string().optional(),\n});\n\n// `code/secret`: one secret the agent's document lists, read for the running\n// `code/run` request `requestId`; the platform resolves it in the project of\n// the session or conversation the host serves.\nexport const localHostSecretParamsSchema = z.strictObject({\n requestId: z.string(),\n name: z.string().min(1),\n});\n\nexport const localHostSecretResultSchema = z.object({\n // Null when the project has no such secret set.\n value: z.string().nullable(),\n});\n\n// The `code/run` result: the invocation's final line.\nexport const localHostCodeResultSchema = z.discriminatedUnion('type', [\n z.object({\n type: z.literal(CodeLineType.Result),\n output: jsonValueSchema,\n modelOutput: jsonValueSchema.optional(),\n }),\n z.object({ type: z.literal(CodeLineType.Error), message: z.string() }),\n]);\n\nexport type LocalHostCodeResultIface = z.infer<typeof localHostCodeResultSchema>;\n\nconst textFrameSchema = z.looseObject({\n method: z.string().optional(),\n id: z.union([z.string(), z.number(), z.null()]).optional(),\n params: z.looseObject({ requestId: z.union([z.string(), z.number()]).optional() }).optional(),\n});\n\nconst isHostId = (id: unknown): boolean =>\n typeof id === 'string' && id.startsWith(LOCAL_HOST_REQUEST_ID_PREFIX);\n\n/** Whether a frame on the shared socket belongs to the host protocol. */\nexport const isHostFrame = (frame: WireFrame): boolean => {\n if (typeof frame !== 'string') return false;\n let raw: unknown;\n try {\n raw = JSON.parse(frame);\n } catch {\n return false;\n }\n const message = textFrameSchema.safeParse(raw);\n if (!message.success) return false;\n const method = message.data.method;\n if (method === CANCEL_REQUEST_METHOD) return isHostId(message.data.params?.requestId);\n if (method != null) return method.startsWith('host/') || method.startsWith('code/');\n return isHostId(message.data.id);\n};\n\nexport interface LocalHostChannelsIface {\n // The sandbox handle RPC's frames.\n sandbox: FrameChannelIface;\n // The host protocol's frames.\n host: FrameChannelIface;\n}\n\n/**\n * Splits the shared socket into the sandbox wire and the host protocol. Both\n * sides of the connection use it; closing either closes the socket.\n */\nexport const splitLocalHostChannel = (socket: FrameChannelIface): LocalHostChannelsIface => {\n type Handlers = Parameters<FrameChannelIface['listen']>[0];\n const make = () => {\n let handlers: Handlers | null = null;\n const pending: WireFrame[] = [];\n let closed: { code: number; reason: string } | null = null;\n const channel: FrameChannelIface = {\n send: (frame) => socket.send(frame),\n close: (code, reason) => socket.close(code, reason),\n listen: (next) => {\n handlers = next;\n for (const frame of pending.splice(0)) next.frame(frame);\n if (closed != null) next.close(closed);\n },\n };\n return {\n channel,\n frame: (frame: WireFrame) => {\n if (handlers == null) pending.push(frame);\n else handlers.frame(frame);\n },\n close: (info: { code: number; reason: string }) => {\n if (closed != null) return;\n closed = info;\n handlers?.close(info);\n },\n };\n };\n const sandbox = make();\n const host = make();\n socket.listen({\n frame: (frame) => (isHostFrame(frame) ? host : sandbox).frame(frame),\n close: (info) => {\n sandbox.close(info);\n host.close(info);\n },\n });\n return { sandbox: sandbox.channel, host: host.channel };\n};\n\nconst hostMessageSchema = z.looseObject({\n method: z.string().optional(),\n id: z.union([z.string(), z.number(), z.null()]).optional(),\n params: jsonValueSchema.optional(),\n result: jsonValueSchema.optional(),\n error: z.looseObject({ code: z.number(), message: z.string() }).optional(),\n});\n\nconst cancelParamsSchema = z.object({ requestId: z.string() });\n\nexport interface HostRequestContextIface {\n id: string;\n params: z.output<typeof jsonValueSchema> | undefined;\n signal: AbortSignal;\n}\n\nexport interface HostPeerIface {\n request: (method: string, params: z.input<typeof jsonValueSchema>) => Promise<unknown>;\n notify: (method: string, params: z.input<typeof jsonValueSchema>) => void;\n close: (code?: number, reason?: string) => void;\n /** Resolves when the socket closes, for any reason. */\n closed: Promise<{ code: number; reason: string }>;\n isClosed: () => boolean;\n}\n\n// JSON-RPC error codes the host protocol answers with.\nexport enum HostRpcErrorCode {\n MethodNotFound = -32601,\n InvalidParams = -32602,\n Internal = -32603,\n Cancelled = -32800,\n}\n\n/**\n * JSON-RPC 2.0 for the host protocol. Ids it sends are strings starting with\n * `host:`, so the far side routes their responses (see `isHostFrame`).\n */\nexport const createHostPeer = (args: {\n channel: FrameChannelIface;\n onRequest?: (method: string, context: HostRequestContextIface) => Promise<unknown>;\n onNotification?: (method: string, params: z.output<typeof jsonValueSchema> | undefined) => void;\n newId?: () => string;\n}): HostPeerIface => {\n let counter = 0;\n const newId = args.newId ?? (() => `${LOCAL_HOST_REQUEST_ID_PREFIX}${++counter}`);\n const pending = new Map<\n string,\n { resolve: (value: unknown) => void; reject: (error: Error) => void }\n >();\n const inbound = new Map<string, AbortController>();\n let closedInfo: { code: number; reason: string } | null = null;\n let resolveClosed: (info: { code: number; reason: string }) => void = () => undefined;\n const closed = new Promise<{ code: number; reason: string }>((resolve) => {\n resolveClosed = resolve;\n });\n const send = (message: Record<string, unknown>) => {\n if (closedInfo == null) args.channel.send(JSON.stringify({ jsonrpc: '2.0', ...message }));\n };\n\n const answer = async (method: string, id: string, params: HostRequestContextIface['params']) => {\n const controller = new AbortController();\n inbound.set(id, controller);\n try {\n const handler = args.onRequest;\n if (handler == null) {\n send({ id, error: { code: HostRpcErrorCode.MethodNotFound, message: method } });\n return;\n }\n const result = await handler(method, { id, params, signal: controller.signal });\n send(\n controller.signal.aborted\n ? { id, error: { code: HostRpcErrorCode.Cancelled, message: 'request cancelled' } }\n : { id, result: result ?? {} },\n );\n } catch (cause) {\n send({\n id,\n error: {\n code: HostRpcErrorCode.Internal,\n message: cause instanceof Error ? cause.message : String(cause),\n },\n });\n } finally {\n inbound.delete(id);\n }\n };\n\n args.channel.listen({\n frame: (frame) => {\n if (typeof frame !== 'string') return;\n let raw: unknown;\n try {\n raw = JSON.parse(frame);\n } catch {\n return;\n }\n const message = hostMessageSchema.safeParse(raw);\n if (!message.success) return;\n const { method, id } = message.data;\n if (method === CANCEL_REQUEST_METHOD) {\n const cancel = cancelParamsSchema.safeParse(message.data.params);\n if (cancel.success) inbound.get(cancel.data.requestId)?.abort();\n return;\n }\n if (method != null) {\n if (id == null) args.onNotification?.(method, message.data.params);\n else void answer(method, String(id), message.data.params);\n return;\n }\n if (typeof id !== 'string') return;\n const waiter = pending.get(id);\n if (waiter == null) return;\n pending.delete(id);\n if (message.data.error != null) waiter.reject(new Error(message.data.error.message));\n else waiter.resolve(message.data.result ?? null);\n },\n close: (info) => {\n if (closedInfo != null) return;\n closedInfo = info;\n for (const controller of inbound.values()) controller.abort();\n for (const waiter of pending.values())\n waiter.reject(new Error(`local host connection closed (${info.code})`));\n pending.clear();\n resolveClosed(info);\n },\n });\n\n return {\n request: (method, params) => {\n if (closedInfo != null) return Promise.reject(new Error('local host connection is closed'));\n const id = newId();\n return new Promise<unknown>((resolve, reject) => {\n pending.set(id, { resolve, reject });\n send({ id, method, params });\n });\n },\n notify: (method, params) => send({ method, params }),\n close: (code, reason) => args.channel.close(code, reason),\n closed,\n isClosed: () => closedInfo != null,\n };\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["LocalHostMethod", "LocalHostOwnerKind", "HostRpcErrorCode"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type Capability } from '@finalai/agent-protocol';
|
|
2
|
+
import { type CodeSandboxEndpointIface } from '@finalai/agent-provider/code-host';
|
|
3
|
+
import type { SandboxClientIface } from '@finalai/agent-provider/sandbox/client';
|
|
4
|
+
import type { NetworkSandboxSessionIface } from '@finalai/agent-provider/sandbox/types';
|
|
5
|
+
import type { FrameChannelIface } from '@finalai/agent-provider/sandbox/wire';
|
|
6
|
+
import type { ResolvedAgentIface } from "./agent-input.mjs";
|
|
7
|
+
import { type LocalHostOwnerIface } from "./local-host-protocol.mjs";
|
|
8
|
+
export interface LocalComputeIface {
|
|
9
|
+
/** The sandbox this process serves `files` and `shell` from. */
|
|
10
|
+
sandbox: () => Promise<NetworkSandboxSessionIface>;
|
|
11
|
+
/** Connects `ctx.sandbox(capability)` in in-process code to a sandbox endpoint. */
|
|
12
|
+
openSandbox: (endpoint: CodeSandboxEndpointIface) => Promise<SandboxClientIface>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Whether the socket keeps this Node process alive. The connection holds it
|
|
16
|
+
* while it starts and while the platform is using it (a code call, a sandbox
|
|
17
|
+
* operation, a running command), and lets an idle script exit.
|
|
18
|
+
*/
|
|
19
|
+
export interface LocalHostKeepAliveIface {
|
|
20
|
+
ref: () => void;
|
|
21
|
+
unref: () => void;
|
|
22
|
+
}
|
|
23
|
+
export interface LocalHostSocketIface extends FrameChannelIface {
|
|
24
|
+
/** Absent: the socket's lifetime is not this process's concern. */
|
|
25
|
+
keepAlive?: LocalHostKeepAliveIface;
|
|
26
|
+
}
|
|
27
|
+
export interface OpenLocalHostArgsIface {
|
|
28
|
+
/** Opens the socket at an API path (`/v1/projects/:id/local-hosts`), referenced. */
|
|
29
|
+
dial: (path: string, signal?: AbortSignal) => Promise<LocalHostSocketIface>;
|
|
30
|
+
projectId: string;
|
|
31
|
+
owner: LocalHostOwnerIface;
|
|
32
|
+
agent: ResolvedAgentIface;
|
|
33
|
+
/** Capabilities served from this process; may be empty. */
|
|
34
|
+
capabilities: Capability[];
|
|
35
|
+
compute: LocalComputeIface;
|
|
36
|
+
/** Abandons opening: the connection closes and whatever it started stops. */
|
|
37
|
+
signal?: AbortSignal;
|
|
38
|
+
}
|
|
39
|
+
export interface LocalHostIface {
|
|
40
|
+
hostId: string;
|
|
41
|
+
/** The session or conversation id the platform reserved or confirmed. */
|
|
42
|
+
ownerId: string;
|
|
43
|
+
/** What names this process's compute in `provide.compute`; null when it serves none. */
|
|
44
|
+
sandboxId: string | null;
|
|
45
|
+
closed: Promise<{
|
|
46
|
+
code: number;
|
|
47
|
+
reason: string;
|
|
48
|
+
}>;
|
|
49
|
+
close: () => void;
|
|
50
|
+
/**
|
|
51
|
+
* The session or conversation it serves exists: the socket stops keeping
|
|
52
|
+
* the process alive while nothing uses it.
|
|
53
|
+
*/
|
|
54
|
+
established: () => void;
|
|
55
|
+
}
|
|
56
|
+
export declare const openLocalHost: (args: OpenLocalHostArgsIface) => Promise<LocalHostIface>;
|