@farm.js/agent 0.0.0-stage → 0.1.0-beta.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/LICENSE +22 -0
- package/README.md +22 -2
- package/dist/config.d.ts +12 -0
- package/dist/config.js +19 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +144 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Farm.js Team
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
package/README.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @farm.js/agent
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Durable agents for Farm.js, served and built by [agent-unit](https://github.com/farming-labs/agent-unit)
|
|
4
|
+
|
|
5
|
+
See [Stability and Support](https://farmjs.dev/docs/stability) for what this package guarantees.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @farm.js/agent agent-unit
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
// farm.config.ts
|
|
13
|
+
import { agent } from "@farm.js/agent";
|
|
14
|
+
import { defineConfig } from "@farm.js/core";
|
|
15
|
+
|
|
16
|
+
export default defineConfig({
|
|
17
|
+
integrations: {
|
|
18
|
+
agent: agent({ storage: { driver: "redis", url: process.env.REDIS_URL } }),
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
See the [durable agents guide](https://farmjs.dev/docs/integrations/agent) for agents, the API, storage, and deploy targets.
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { AgentUnitConfig } from 'agent-unit';
|
|
2
|
+
|
|
3
|
+
/** @internal Called by `agent()` as farm.config evaluates, in Farm's process and in the server. */
|
|
4
|
+
declare function registerAgentUnitConfig(config: AgentUnitConfig): void;
|
|
5
|
+
/**
|
|
6
|
+
* The agent-unit config of the app's `agent()` integration. agent-unit's engine reads it when it is
|
|
7
|
+
* first used: by then Farm's server has evaluated farm.config, so settings such as storage URLs and
|
|
8
|
+
* `authorize` come from where the server runs.
|
|
9
|
+
*/
|
|
10
|
+
declare function agentUnitConfig(): AgentUnitConfig;
|
|
11
|
+
|
|
12
|
+
export { agentUnitConfig as default, registerAgentUnitConfig };
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// src/config.ts
|
|
2
|
+
var AGENT_UNIT_CONFIG = /* @__PURE__ */ Symbol.for("farm.agent.config");
|
|
3
|
+
function registerAgentUnitConfig(config) {
|
|
4
|
+
globalThis[AGENT_UNIT_CONFIG] = config;
|
|
5
|
+
}
|
|
6
|
+
function agentUnitConfig() {
|
|
7
|
+
const config = globalThis[AGENT_UNIT_CONFIG];
|
|
8
|
+
if (!config) {
|
|
9
|
+
throw new Error(
|
|
10
|
+
"@farm.js/agent: the server has not evaluated farm.config, so the agent() settings are missing. Mount agent() under `integrations` in farm.config."
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
return config;
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
agentUnitConfig as default,
|
|
17
|
+
registerAgentUnitConfig
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config.ts"],"sourcesContent":["import type { AgentUnitConfig } from \"agent-unit\";\n\nconst AGENT_UNIT_CONFIG = Symbol.for(\"farm.agent.config\");\n\ntype ConfigHolder = { [AGENT_UNIT_CONFIG]?: AgentUnitConfig };\n\n/** @internal Called by `agent()` as farm.config evaluates, in Farm's process and in the server. */\nexport function registerAgentUnitConfig(config: AgentUnitConfig): void {\n (globalThis as ConfigHolder)[AGENT_UNIT_CONFIG] = config;\n}\n\n/**\n * The agent-unit config of the app's `agent()` integration. agent-unit's engine reads it when it is\n * first used: by then Farm's server has evaluated farm.config, so settings such as storage URLs and\n * `authorize` come from where the server runs.\n */\nexport default function agentUnitConfig(): AgentUnitConfig {\n const config = (globalThis as ConfigHolder)[AGENT_UNIT_CONFIG];\n if (!config) {\n throw new Error(\n \"@farm.js/agent: the server has not evaluated farm.config, so the agent() settings are missing. Mount agent() under `integrations` in farm.config.\",\n );\n }\n return config;\n}\n"],"mappings":";AAEA,IAAM,oBAAoB,uBAAO,IAAI,mBAAmB;AAKjD,SAAS,wBAAwB,QAA+B;AACrE,EAAC,WAA4B,iBAAiB,IAAI;AACpD;AAOe,SAAR,kBAAoD;AACzD,QAAM,SAAU,WAA4B,iBAAiB;AAC7D,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as _farm_js_core from '@farm.js/core';
|
|
2
|
+
import { AgentFramework, AgentUnitConfig } from 'agent-unit';
|
|
3
|
+
export { AgentFramework } from 'agent-unit';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* agent-unit's settings, minus what Farm owns: the host (`deploy.target`), the server and the
|
|
7
|
+
* Nitro and Workers settings, which belong in farm.config.
|
|
8
|
+
*/
|
|
9
|
+
interface AgentOptions extends Omit<AgentUnitConfig, "server" | "preset" | "runtime" | "cloudflare" | "nitro"> {
|
|
10
|
+
/** Where the agent API is mounted. It owns every path under it. Default `/api/agent`. */
|
|
11
|
+
basePath?: string;
|
|
12
|
+
/** The folder of agent files, relative to the app root. Default `agents` in `srcDir`. */
|
|
13
|
+
agentsDir?: string;
|
|
14
|
+
}
|
|
15
|
+
interface AgentInstance {
|
|
16
|
+
readonly basePath: string;
|
|
17
|
+
readonly framework?: AgentFramework;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Durable agents in a Farm app: the agents in `src/agents`, written with the AI SDK, Mastra,
|
|
21
|
+
* LangGraph, the OpenAI Agents SDK or agent-unit's `defineAgent`, served under `basePath` in
|
|
22
|
+
* `farm dev` and built by agent-unit into every deployment target.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* integrations: { agent: agent({ framework: "ai-sdk", storage: { driver: "redis", url: process.env.REDIS_URL } }) }
|
|
26
|
+
*/
|
|
27
|
+
declare function agent(options?: AgentOptions): _farm_js_core.DefinedIntegration<{
|
|
28
|
+
category: "agent";
|
|
29
|
+
type: string;
|
|
30
|
+
instance: AgentInstance;
|
|
31
|
+
plugins: _farm_js_core.FarmPlugin<undefined, Record<string, never>, unknown, undefined, unknown, false, _farm_js_core.PluginRoutes>[];
|
|
32
|
+
}, _farm_js_core.FarmSchema | undefined>;
|
|
33
|
+
|
|
34
|
+
export { type AgentInstance, type AgentOptions, agent };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { defineIntegration } from "@farm.js/core";
|
|
3
|
+
|
|
4
|
+
// src/config.ts
|
|
5
|
+
var AGENT_UNIT_CONFIG = /* @__PURE__ */ Symbol.for("farm.agent.config");
|
|
6
|
+
function registerAgentUnitConfig(config) {
|
|
7
|
+
globalThis[AGENT_UNIT_CONFIG] = config;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// src/plugin.ts
|
|
11
|
+
import path from "path";
|
|
12
|
+
import { Readable } from "stream";
|
|
13
|
+
import { fileURLToPath } from "url";
|
|
14
|
+
import { definePlugin } from "@farm.js/core/plugin";
|
|
15
|
+
var loadBuildOnly = (specifier) => import(
|
|
16
|
+
/* @vite-ignore */
|
|
17
|
+
specifier
|
|
18
|
+
);
|
|
19
|
+
function isUnder(pathname, basePath) {
|
|
20
|
+
return basePath === "/" || pathname === basePath || pathname.startsWith(`${basePath}/`);
|
|
21
|
+
}
|
|
22
|
+
function createAgentPlugin(config) {
|
|
23
|
+
const { basePath } = config;
|
|
24
|
+
let root;
|
|
25
|
+
let agentsDir = config.agentsDir ?? "agents";
|
|
26
|
+
let devHandler;
|
|
27
|
+
const closeDev = async () => {
|
|
28
|
+
const pending = devHandler;
|
|
29
|
+
devHandler = void 0;
|
|
30
|
+
await (await pending?.catch(() => void 0))?.close();
|
|
31
|
+
};
|
|
32
|
+
const buildConfig = () => ({ ...config, agentsDir });
|
|
33
|
+
const devPlugin = {
|
|
34
|
+
name: "farm:agent-dev",
|
|
35
|
+
apply: "serve",
|
|
36
|
+
// Ahead of Farm's API middleware, which answers 404 for API paths it does not route.
|
|
37
|
+
enforce: "pre",
|
|
38
|
+
// Vite runs this again on every restart, while the agents keep running in one dev handler.
|
|
39
|
+
configureServer(server) {
|
|
40
|
+
devHandler ??= loadBuildOnly("agent-unit/build").then(
|
|
41
|
+
({ createDevHandler }) => createDevHandler({ root: root ?? process.cwd(), config: buildConfig() })
|
|
42
|
+
);
|
|
43
|
+
const handler = devHandler;
|
|
44
|
+
server.middlewares.use((req, res, next) => {
|
|
45
|
+
if (!isUnder((req.url ?? "/").split("?")[0], basePath)) return next();
|
|
46
|
+
void serveDev(handler, req, res).catch(next);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
return definePlugin({
|
|
51
|
+
name: "farm:agent",
|
|
52
|
+
configure(farmConfig, context) {
|
|
53
|
+
root = path.resolve(farmConfig.root ?? process.cwd());
|
|
54
|
+
agentsDir = config.agentsDir ?? path.posix.join(farmConfig.srcDir ?? "src", "agents");
|
|
55
|
+
if (!context.isDev) return;
|
|
56
|
+
const vite = farmConfig.vite ?? {};
|
|
57
|
+
return { ...farmConfig, vite: { ...vite, plugins: [devPlugin, ...vite.plugins ?? []] } };
|
|
58
|
+
},
|
|
59
|
+
router: {
|
|
60
|
+
// agent-unit answers every path under basePath, so an app route there would never be reached.
|
|
61
|
+
discovered(route) {
|
|
62
|
+
if (route.kind !== "api" || !isUnder(route.path, basePath)) return;
|
|
63
|
+
throw new Error(
|
|
64
|
+
`@farm.js/agent: ${route.filePath} is served at ${route.path}, which the agent API owns (basePath "${basePath}"). Move the route, or set another basePath.`
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
build: {
|
|
69
|
+
// agent-unit builds the agents into Farm's Nitro output for its preset: their framework
|
|
70
|
+
// adapters, storage, the sweep and `tasks` as scheduled tasks.
|
|
71
|
+
async configure(nitroConfig) {
|
|
72
|
+
const { agentUnit } = await loadBuildOnly("agent-unit/nitro");
|
|
73
|
+
const module = agentUnit({
|
|
74
|
+
root: root ?? process.cwd(),
|
|
75
|
+
basePath,
|
|
76
|
+
config: buildConfig(),
|
|
77
|
+
// The module agent-unit's engine reads its config from in the built server.
|
|
78
|
+
configFile: fileURLToPath(new URL("./config.js", import.meta.url))
|
|
79
|
+
});
|
|
80
|
+
return { ...nitroConfig, modules: [...nitroConfig.modules ?? [], module] };
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
dev: {
|
|
84
|
+
server(_viteServer, { lifecycle }) {
|
|
85
|
+
lifecycle.onShutdown(closeDev);
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
runtime: {
|
|
89
|
+
close: closeDev
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
async function serveDev(handler, req, res) {
|
|
94
|
+
const { sendWebResponse } = await loadBuildOnly("@farm.js/core/server");
|
|
95
|
+
const response = await (await handler).fetch(toWebRequest(req, res));
|
|
96
|
+
await sendWebResponse(res, response);
|
|
97
|
+
}
|
|
98
|
+
function toWebRequest(req, res) {
|
|
99
|
+
const protocol = req.socket.encrypted ? "https" : "http";
|
|
100
|
+
const url = new URL(req.url ?? "/", `${protocol}://${req.headers.host ?? "localhost"}`);
|
|
101
|
+
const headers = new Headers();
|
|
102
|
+
for (let index = 0; index < req.rawHeaders.length; index += 2) {
|
|
103
|
+
const name = req.rawHeaders[index];
|
|
104
|
+
if (!name.startsWith(":")) headers.append(name, req.rawHeaders[index + 1]);
|
|
105
|
+
}
|
|
106
|
+
const controller = new AbortController();
|
|
107
|
+
res.once("close", () => {
|
|
108
|
+
if (!res.writableFinished) controller.abort();
|
|
109
|
+
});
|
|
110
|
+
const method = req.method ?? "GET";
|
|
111
|
+
const hasBody = method !== "GET" && method !== "HEAD";
|
|
112
|
+
return new Request(url, {
|
|
113
|
+
method,
|
|
114
|
+
headers,
|
|
115
|
+
signal: controller.signal,
|
|
116
|
+
body: hasBody ? Readable.toWeb(req) : void 0,
|
|
117
|
+
...hasBody ? { duplex: "half" } : {}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// src/index.ts
|
|
122
|
+
var DEFAULT_BASE_PATH = "/api/agent";
|
|
123
|
+
function normalizeBasePath(value) {
|
|
124
|
+
if (!value.startsWith("/")) {
|
|
125
|
+
throw new Error(`@farm.js/agent: basePath must start with "/", got "${value}".`);
|
|
126
|
+
}
|
|
127
|
+
return value.replace(/\/+$/, "") || "/";
|
|
128
|
+
}
|
|
129
|
+
function agent(options = {}) {
|
|
130
|
+
const basePath = normalizeBasePath(options.basePath ?? DEFAULT_BASE_PATH);
|
|
131
|
+
const config = { ...options, basePath };
|
|
132
|
+
const instance = { basePath, framework: options.framework };
|
|
133
|
+
registerAgentUnitConfig(config);
|
|
134
|
+
return defineIntegration({
|
|
135
|
+
category: "agent",
|
|
136
|
+
type: "agent-unit",
|
|
137
|
+
instance,
|
|
138
|
+
plugins: [createAgentPlugin(config)]
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
export {
|
|
142
|
+
agent
|
|
143
|
+
};
|
|
144
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/plugin.ts"],"sourcesContent":["import { defineIntegration } from \"@farm.js/core\";\nimport type { AgentFramework, AgentUnitConfig } from \"agent-unit\";\n\nimport { registerAgentUnitConfig } from \"./config.js\";\nimport { createAgentPlugin } from \"./plugin.js\";\n\nexport type { AgentFramework };\n\n/**\n * agent-unit's settings, minus what Farm owns: the host (`deploy.target`), the server and the\n * Nitro and Workers settings, which belong in farm.config.\n */\nexport interface AgentOptions extends Omit<\n AgentUnitConfig,\n \"server\" | \"preset\" | \"runtime\" | \"cloudflare\" | \"nitro\"\n> {\n /** Where the agent API is mounted. It owns every path under it. Default `/api/agent`. */\n basePath?: string;\n /** The folder of agent files, relative to the app root. Default `agents` in `srcDir`. */\n agentsDir?: string;\n}\n\nexport interface AgentInstance {\n readonly basePath: string;\n readonly framework?: AgentFramework;\n}\n\nconst DEFAULT_BASE_PATH = \"/api/agent\";\n\nfunction normalizeBasePath(value: string): string {\n if (!value.startsWith(\"/\")) {\n throw new Error(`@farm.js/agent: basePath must start with \"/\", got \"${value}\".`);\n }\n return value.replace(/\\/+$/, \"\") || \"/\";\n}\n\n/**\n * Durable agents in a Farm app: the agents in `src/agents`, written with the AI SDK, Mastra,\n * LangGraph, the OpenAI Agents SDK or agent-unit's `defineAgent`, served under `basePath` in\n * `farm dev` and built by agent-unit into every deployment target.\n *\n * @example\n * integrations: { agent: agent({ framework: \"ai-sdk\", storage: { driver: \"redis\", url: process.env.REDIS_URL } }) }\n */\nexport function agent(options: AgentOptions = {}) {\n const basePath = normalizeBasePath(options.basePath ?? DEFAULT_BASE_PATH);\n const config: AgentUnitConfig & { basePath: string } = { ...options, basePath };\n const instance: AgentInstance = { basePath, framework: options.framework };\n // agent-unit's engine reads it from the server that evaluates farm.config (see ./config).\n registerAgentUnitConfig(config);\n\n return defineIntegration({\n category: \"agent\",\n type: \"agent-unit\",\n instance,\n plugins: [createAgentPlugin(config)],\n });\n}\n","import type { AgentUnitConfig } from \"agent-unit\";\n\nconst AGENT_UNIT_CONFIG = Symbol.for(\"farm.agent.config\");\n\ntype ConfigHolder = { [AGENT_UNIT_CONFIG]?: AgentUnitConfig };\n\n/** @internal Called by `agent()` as farm.config evaluates, in Farm's process and in the server. */\nexport function registerAgentUnitConfig(config: AgentUnitConfig): void {\n (globalThis as ConfigHolder)[AGENT_UNIT_CONFIG] = config;\n}\n\n/**\n * The agent-unit config of the app's `agent()` integration. agent-unit's engine reads it when it is\n * first used: by then Farm's server has evaluated farm.config, so settings such as storage URLs and\n * `authorize` come from where the server runs.\n */\nexport default function agentUnitConfig(): AgentUnitConfig {\n const config = (globalThis as ConfigHolder)[AGENT_UNIT_CONFIG];\n if (!config) {\n throw new Error(\n \"@farm.js/agent: the server has not evaluated farm.config, so the agent() settings are missing. Mount agent() under `integrations` in farm.config.\",\n );\n }\n return config;\n}\n","import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport path from \"node:path\";\nimport { Readable } from \"node:stream\";\nimport type { TLSSocket } from \"node:tls\";\nimport { fileURLToPath } from \"node:url\";\nimport { definePlugin } from \"@farm.js/core/plugin\";\nimport type { AgentUnitConfig } from \"agent-unit\";\nimport type { DevHandler } from \"agent-unit/build\";\nimport type { Plugin as VitePlugin } from \"vite\";\n\n// agent-unit's build and dev servers load only in Farm's own process. Farm bundles farm.config into\n// the production server, and a bundler follows literal imports, so these must not be literal.\nconst loadBuildOnly = <T>(specifier: string): Promise<T> => import(/* @vite-ignore */ specifier);\n\nexport function isUnder(pathname: string, basePath: string): boolean {\n return basePath === \"/\" || pathname === basePath || pathname.startsWith(`${basePath}/`);\n}\n\n/** Serves the agents in `farm dev` and builds them into the production server. */\nexport function createAgentPlugin(config: AgentUnitConfig & { basePath: string }) {\n const { basePath } = config;\n // Set by `configure`, in Farm's process: farm.config also evaluates inside the server, where a\n // Worker has no working directory.\n let root: string | undefined;\n let agentsDir = config.agentsDir ?? \"agents\";\n let devHandler: Promise<DevHandler> | undefined;\n\n const closeDev = async () => {\n const pending = devHandler;\n devHandler = undefined;\n await (await pending?.catch(() => undefined))?.close();\n };\n const buildConfig = (): AgentUnitConfig => ({ ...config, agentsDir });\n\n const devPlugin: VitePlugin = {\n name: \"farm:agent-dev\",\n apply: \"serve\",\n // Ahead of Farm's API middleware, which answers 404 for API paths it does not route.\n enforce: \"pre\",\n // Vite runs this again on every restart, while the agents keep running in one dev handler.\n configureServer(server) {\n devHandler ??= loadBuildOnly<typeof import(\"agent-unit/build\")>(\"agent-unit/build\").then(\n ({ createDevHandler }) =>\n createDevHandler({ root: root ?? process.cwd(), config: buildConfig() }),\n );\n const handler = devHandler;\n server.middlewares.use((req, res, next) => {\n if (!isUnder((req.url ?? \"/\").split(\"?\")[0]!, basePath)) return next();\n void serveDev(handler, req, res).catch(next);\n });\n },\n };\n\n return definePlugin({\n name: \"farm:agent\",\n configure(farmConfig, context) {\n root = path.resolve(farmConfig.root ?? process.cwd());\n agentsDir = config.agentsDir ?? path.posix.join(farmConfig.srcDir ?? \"src\", \"agents\");\n if (!context.isDev) return;\n const vite = farmConfig.vite ?? {};\n return { ...farmConfig, vite: { ...vite, plugins: [devPlugin, ...(vite.plugins ?? [])] } };\n },\n router: {\n // agent-unit answers every path under basePath, so an app route there would never be reached.\n discovered(route) {\n if (route.kind !== \"api\" || !isUnder(route.path, basePath)) return;\n throw new Error(\n `@farm.js/agent: ${route.filePath} is served at ${route.path}, which the agent API owns (basePath \"${basePath}\"). Move the route, or set another basePath.`,\n );\n },\n },\n build: {\n // agent-unit builds the agents into Farm's Nitro output for its preset: their framework\n // adapters, storage, the sweep and `tasks` as scheduled tasks.\n async configure(nitroConfig) {\n const { agentUnit } =\n await loadBuildOnly<typeof import(\"agent-unit/nitro\")>(\"agent-unit/nitro\");\n const module = agentUnit({\n root: root ?? process.cwd(),\n basePath,\n config: buildConfig(),\n // The module agent-unit's engine reads its config from in the built server.\n configFile: fileURLToPath(new URL(\"./config.js\", import.meta.url)),\n });\n return { ...nitroConfig, modules: [...(nitroConfig.modules ?? []), module] };\n },\n },\n dev: {\n server(_viteServer, { lifecycle }) {\n lifecycle.onShutdown(closeDev);\n },\n },\n runtime: {\n close: closeDev,\n },\n });\n}\n\nasync function serveDev(\n handler: Promise<DevHandler>,\n req: IncomingMessage,\n res: ServerResponse,\n): Promise<void> {\n const { sendWebResponse } =\n await loadBuildOnly<typeof import(\"@farm.js/core/server\")>(\"@farm.js/core/server\");\n const response = await (await handler).fetch(toWebRequest(req, res));\n await sendWebResponse(res, response);\n}\n\nfunction toWebRequest(req: IncomingMessage, res: ServerResponse): Request {\n const protocol = (req.socket as TLSSocket).encrypted ? \"https\" : \"http\";\n const url = new URL(req.url ?? \"/\", `${protocol}://${req.headers.host ?? \"localhost\"}`);\n const headers = new Headers();\n for (let index = 0; index < req.rawHeaders.length; index += 2) {\n const name = req.rawHeaders[index]!;\n if (!name.startsWith(\":\")) headers.append(name, req.rawHeaders[index + 1]!);\n }\n // A client that leaves an event stream ends the run's subscription, not the run.\n const controller = new AbortController();\n res.once(\"close\", () => {\n if (!res.writableFinished) controller.abort();\n });\n const method = req.method ?? \"GET\";\n const hasBody = method !== \"GET\" && method !== \"HEAD\";\n return new Request(url, {\n method,\n headers,\n signal: controller.signal,\n body: hasBody ? (Readable.toWeb(req) as ReadableStream<Uint8Array>) : undefined,\n ...(hasBody ? { duplex: \"half\" } : {}),\n } as RequestInit);\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,61 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@farm.js/agent",
|
|
3
|
-
"version": "0.0.0
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.0-beta.0",
|
|
4
|
+
"description": "Durable agents for Farm.js, served and built by agent-unit",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"agent-unit",
|
|
7
|
+
"agents",
|
|
8
|
+
"ai-sdk",
|
|
9
|
+
"farmjs",
|
|
10
|
+
"mastra"
|
|
11
|
+
],
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/farming-labs/farm.js",
|
|
16
|
+
"directory": "packages/farm-agent"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"type": "module",
|
|
22
|
+
"main": "./dist/index.js",
|
|
23
|
+
"module": "./dist/index.js",
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"import": "./dist/index.js"
|
|
29
|
+
},
|
|
30
|
+
"./config": {
|
|
31
|
+
"types": "./dist/config.d.ts",
|
|
32
|
+
"import": "./dist/config.js"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"agent-unit": "^0.3.0"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@types/node": "^22.20.5",
|
|
43
|
+
"tsup": "^8.5.1",
|
|
44
|
+
"typescript": "^5.3.3",
|
|
45
|
+
"vite": "8.3.4",
|
|
46
|
+
"vitest": "5.0.5",
|
|
47
|
+
"@farm.js/core": "0.1.48"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"@farm.js/core": ">=0.1.48 <0.2.0"
|
|
51
|
+
},
|
|
52
|
+
"engines": {
|
|
53
|
+
"node": ">=22.13.0"
|
|
54
|
+
},
|
|
55
|
+
"scripts": {
|
|
56
|
+
"build": "tsup",
|
|
57
|
+
"dev": "tsup --watch",
|
|
58
|
+
"test": "vitest run",
|
|
59
|
+
"type-check": "tsc --noEmit"
|
|
60
|
+
}
|
|
6
61
|
}
|