@better-agent/core 0.1.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/README.md +3 -0
  2. package/dist/agent/constants.mjs +6 -0
  3. package/dist/agent/constants.mjs.map +1 -0
  4. package/dist/agent/define-agent.d.mts +29 -0
  5. package/dist/agent/define-agent.d.mts.map +1 -0
  6. package/dist/agent/define-agent.mjs +27 -0
  7. package/dist/agent/define-agent.mjs.map +1 -0
  8. package/dist/agent/index.d.mts +2 -0
  9. package/dist/agent/types.d.mts +216 -0
  10. package/dist/agent/types.d.mts.map +1 -0
  11. package/dist/agent/validation.mjs +64 -0
  12. package/dist/agent/validation.mjs.map +1 -0
  13. package/dist/api.d.mts +8 -0
  14. package/dist/api.d.mts.map +1 -0
  15. package/dist/api.mjs +63 -0
  16. package/dist/api.mjs.map +1 -0
  17. package/dist/app/config.mjs +43 -0
  18. package/dist/app/config.mjs.map +1 -0
  19. package/dist/app/create-app.d.mts +36 -0
  20. package/dist/app/create-app.d.mts.map +1 -0
  21. package/dist/app/create-app.mjs +132 -0
  22. package/dist/app/create-app.mjs.map +1 -0
  23. package/dist/app/registry.mjs +43 -0
  24. package/dist/app/registry.mjs.map +1 -0
  25. package/dist/app/types.d.mts +142 -0
  26. package/dist/app/types.d.mts.map +1 -0
  27. package/dist/events/constants.d.mts +49 -0
  28. package/dist/events/constants.d.mts.map +1 -0
  29. package/dist/events/constants.mjs +46 -0
  30. package/dist/events/constants.mjs.map +1 -0
  31. package/dist/events/index.d.mts +4 -0
  32. package/dist/events/index.mjs +3 -0
  33. package/dist/events/types.d.mts +289 -0
  34. package/dist/events/types.d.mts.map +1 -0
  35. package/dist/index.d.mts +23 -0
  36. package/dist/index.mjs +14 -0
  37. package/dist/internal/id.mjs +21 -0
  38. package/dist/internal/id.mjs.map +1 -0
  39. package/dist/internal/types.d.mts +11 -0
  40. package/dist/internal/types.d.mts.map +1 -0
  41. package/dist/mcp/error/mcp-client-error.d.mts +36 -0
  42. package/dist/mcp/error/mcp-client-error.d.mts.map +1 -0
  43. package/dist/mcp/error/mcp-client-error.mjs +33 -0
  44. package/dist/mcp/error/mcp-client-error.mjs.map +1 -0
  45. package/dist/mcp/index.d.mts +8 -0
  46. package/dist/mcp/index.mjs +9 -0
  47. package/dist/mcp/tool/json-rpc-message.d.mts +50 -0
  48. package/dist/mcp/tool/json-rpc-message.d.mts.map +1 -0
  49. package/dist/mcp/tool/json-rpc-message.mjs +84 -0
  50. package/dist/mcp/tool/json-rpc-message.mjs.map +1 -0
  51. package/dist/mcp/tool/mcp-client.d.mts +71 -0
  52. package/dist/mcp/tool/mcp-client.d.mts.map +1 -0
  53. package/dist/mcp/tool/mcp-client.mjs +304 -0
  54. package/dist/mcp/tool/mcp-client.mjs.map +1 -0
  55. package/dist/mcp/tool/mcp-http-transport.d.mts +62 -0
  56. package/dist/mcp/tool/mcp-http-transport.d.mts.map +1 -0
  57. package/dist/mcp/tool/mcp-http-transport.mjs +307 -0
  58. package/dist/mcp/tool/mcp-http-transport.mjs.map +1 -0
  59. package/dist/mcp/tool/mcp-tools.d.mts +20 -0
  60. package/dist/mcp/tool/mcp-tools.d.mts.map +1 -0
  61. package/dist/mcp/tool/mcp-tools.mjs +73 -0
  62. package/dist/mcp/tool/mcp-tools.mjs.map +1 -0
  63. package/dist/mcp/tool/mcp-transport.d.mts +81 -0
  64. package/dist/mcp/tool/mcp-transport.d.mts.map +1 -0
  65. package/dist/mcp/tool/mcp-transport.mjs +11 -0
  66. package/dist/mcp/tool/mcp-transport.mjs.map +1 -0
  67. package/dist/mcp/tool/types.d.mts +230 -0
  68. package/dist/mcp/tool/types.d.mts.map +1 -0
  69. package/dist/mcp/tool/types.mjs +19 -0
  70. package/dist/mcp/tool/types.mjs.map +1 -0
  71. package/dist/persistence/index.d.mts +3 -0
  72. package/dist/persistence/index.mjs +3 -0
  73. package/dist/persistence/memory.d.mts +21 -0
  74. package/dist/persistence/memory.d.mts.map +1 -0
  75. package/dist/persistence/memory.mjs +107 -0
  76. package/dist/persistence/memory.mjs.map +1 -0
  77. package/dist/persistence/types.d.mts +124 -0
  78. package/dist/persistence/types.d.mts.map +1 -0
  79. package/dist/plugins/index.d.mts +2 -0
  80. package/dist/plugins/runtime.d.mts +17 -0
  81. package/dist/plugins/runtime.d.mts.map +1 -0
  82. package/dist/plugins/runtime.mjs +456 -0
  83. package/dist/plugins/runtime.mjs.map +1 -0
  84. package/dist/plugins/types.d.mts +344 -0
  85. package/dist/plugins/types.d.mts.map +1 -0
  86. package/dist/providers/index.d.mts +9 -0
  87. package/dist/providers/index.mjs +0 -0
  88. package/dist/providers/types/capabilities.d.mts +153 -0
  89. package/dist/providers/types/capabilities.d.mts.map +1 -0
  90. package/dist/providers/types/content.d.mts +125 -0
  91. package/dist/providers/types/content.d.mts.map +1 -0
  92. package/dist/providers/types/conversation.d.mts +32 -0
  93. package/dist/providers/types/conversation.d.mts.map +1 -0
  94. package/dist/providers/types/index.d.mts +8 -0
  95. package/dist/providers/types/input.d.mts +74 -0
  96. package/dist/providers/types/input.d.mts.map +1 -0
  97. package/dist/providers/types/model.d.mts +68 -0
  98. package/dist/providers/types/model.d.mts.map +1 -0
  99. package/dist/providers/types/output.d.mts +29 -0
  100. package/dist/providers/types/output.d.mts.map +1 -0
  101. package/dist/providers/types/response.d.mts +35 -0
  102. package/dist/providers/types/response.d.mts.map +1 -0
  103. package/dist/providers/types/tool-calls.d.mts +51 -0
  104. package/dist/providers/types/tool-calls.d.mts.map +1 -0
  105. package/dist/run/agent-loop.mjs +231 -0
  106. package/dist/run/agent-loop.mjs.map +1 -0
  107. package/dist/run/event-queue.mjs +67 -0
  108. package/dist/run/event-queue.mjs.map +1 -0
  109. package/dist/run/execute-tool-calls.mjs +550 -0
  110. package/dist/run/execute-tool-calls.mjs.map +1 -0
  111. package/dist/run/execution.mjs +93 -0
  112. package/dist/run/execution.mjs.map +1 -0
  113. package/dist/run/helpers.mjs +466 -0
  114. package/dist/run/helpers.mjs.map +1 -0
  115. package/dist/run/hooks.mjs +124 -0
  116. package/dist/run/hooks.mjs.map +1 -0
  117. package/dist/run/index.d.mts +4 -0
  118. package/dist/run/messages.d.mts +8 -0
  119. package/dist/run/messages.d.mts.map +1 -0
  120. package/dist/run/messages.mjs +83 -0
  121. package/dist/run/messages.mjs.map +1 -0
  122. package/dist/run/model-strategy.mjs +105 -0
  123. package/dist/run/model-strategy.mjs.map +1 -0
  124. package/dist/run/output-errors.d.mts +75 -0
  125. package/dist/run/output-errors.d.mts.map +1 -0
  126. package/dist/run/pending-tools.d.mts +1 -0
  127. package/dist/run/pending-tools.mjs +185 -0
  128. package/dist/run/pending-tools.mjs.map +1 -0
  129. package/dist/run/registry.mjs +22 -0
  130. package/dist/run/registry.mjs.map +1 -0
  131. package/dist/run/runtime.d.mts +19 -0
  132. package/dist/run/runtime.d.mts.map +1 -0
  133. package/dist/run/runtime.mjs +491 -0
  134. package/dist/run/runtime.mjs.map +1 -0
  135. package/dist/run/stop-conditions.mjs +41 -0
  136. package/dist/run/stop-conditions.mjs.map +1 -0
  137. package/dist/run/types.d.mts +348 -0
  138. package/dist/run/types.d.mts.map +1 -0
  139. package/dist/schema/index.d.mts +2 -0
  140. package/dist/schema/resolve-json-schema.d.mts +12 -0
  141. package/dist/schema/resolve-json-schema.d.mts.map +1 -0
  142. package/dist/schema/resolve-json-schema.mjs +167 -0
  143. package/dist/schema/resolve-json-schema.mjs.map +1 -0
  144. package/dist/schema/types.d.mts +27 -0
  145. package/dist/schema/types.d.mts.map +1 -0
  146. package/dist/server/create-server.d.mts +21 -0
  147. package/dist/server/create-server.d.mts.map +1 -0
  148. package/dist/server/create-server.mjs +107 -0
  149. package/dist/server/create-server.mjs.map +1 -0
  150. package/dist/server/http.mjs +182 -0
  151. package/dist/server/http.mjs.map +1 -0
  152. package/dist/server/index.d.mts +3 -0
  153. package/dist/server/index.mjs +3 -0
  154. package/dist/server/routes.mjs +399 -0
  155. package/dist/server/routes.mjs.map +1 -0
  156. package/dist/server/types.d.mts +31 -0
  157. package/dist/server/types.d.mts.map +1 -0
  158. package/dist/tools/constants.d.mts +12 -0
  159. package/dist/tools/constants.d.mts.map +1 -0
  160. package/dist/tools/constants.mjs +13 -0
  161. package/dist/tools/constants.mjs.map +1 -0
  162. package/dist/tools/define-tool.d.mts +25 -0
  163. package/dist/tools/define-tool.d.mts.map +1 -0
  164. package/dist/tools/define-tool.mjs +76 -0
  165. package/dist/tools/define-tool.mjs.map +1 -0
  166. package/dist/tools/index.d.mts +5 -0
  167. package/dist/tools/lazy-tools.d.mts +49 -0
  168. package/dist/tools/lazy-tools.d.mts.map +1 -0
  169. package/dist/tools/lazy-tools.mjs +87 -0
  170. package/dist/tools/lazy-tools.mjs.map +1 -0
  171. package/dist/tools/resolve-tools.d.mts +12 -0
  172. package/dist/tools/resolve-tools.d.mts.map +1 -0
  173. package/dist/tools/resolve-tools.mjs +86 -0
  174. package/dist/tools/resolve-tools.mjs.map +1 -0
  175. package/dist/tools/types.d.mts +318 -0
  176. package/dist/tools/types.d.mts.map +1 -0
  177. package/dist/tools/validation.mjs +23 -0
  178. package/dist/tools/validation.mjs.map +1 -0
  179. package/package.json +72 -0
@@ -0,0 +1,167 @@
1
+ import { BetterAgentError } from "@better-agent/shared/errors";
2
+ import { err, ok } from "@better-agent/shared/neverthrow";
3
+ import Ajv from "ajv";
4
+ import Ajv2020 from "ajv/dist/2020.js";
5
+
6
+ //#region src/schema/resolve-json-schema.ts
7
+ const ajvDraft7 = new Ajv({
8
+ allErrors: true,
9
+ logger: false
10
+ });
11
+ const ajvDraft2020 = new Ajv2020({
12
+ allErrors: true,
13
+ logger: false
14
+ });
15
+ const compiledJsonSchemaCache = /* @__PURE__ */ new WeakMap();
16
+ const resolvedStandardJsonSchemaCache = /* @__PURE__ */ new WeakMap();
17
+ const createSchemaError = (params) => params.cause ? BetterAgentError.wrap({
18
+ err: params.cause,
19
+ message: params.message,
20
+ opts: {
21
+ code: "VALIDATION_FAILED",
22
+ context: {
23
+ ...params.context ?? {},
24
+ ...params.issues !== void 0 ? { issues: params.issues } : {}
25
+ },
26
+ trace: [{ at: params.traceAt }]
27
+ }
28
+ }) : BetterAgentError.fromCode("VALIDATION_FAILED", params.message, {
29
+ context: {
30
+ ...params.context ?? {},
31
+ ...params.issues !== void 0 ? { issues: params.issues } : {}
32
+ },
33
+ trace: [{ at: params.traceAt }]
34
+ });
35
+ const compileJsonSchema = (schema, traceAt) => {
36
+ const cachedValidator = compiledJsonSchemaCache.get(schema);
37
+ if (cachedValidator) return ok(cachedValidator);
38
+ const schemaId = schema.$schema;
39
+ const targets = [];
40
+ if (typeof schemaId === "string") if (schemaId.includes("draft-07")) targets.push("draft-07");
41
+ else if (schemaId.includes("draft/2020-12")) targets.push("draft-2020-12");
42
+ else return err(createSchemaError({
43
+ message: "Tool schema uses an unsupported json_schema dialect.",
44
+ traceAt,
45
+ context: {
46
+ schemaType: "json_schema",
47
+ schemaDialect: schemaId
48
+ }
49
+ }));
50
+ else targets.push("draft-07", "draft-2020-12");
51
+ const attempts = [];
52
+ for (const target of targets) try {
53
+ const validator = target === "draft-2020-12" ? ajvDraft2020.compile(schema) : ajvDraft7.compile(schema);
54
+ compiledJsonSchemaCache.set(schema, validator);
55
+ return ok(validator);
56
+ } catch (cause) {
57
+ attempts.push({
58
+ target,
59
+ error: cause instanceof Error ? cause.message : String(cause)
60
+ });
61
+ }
62
+ return err(createSchemaError({
63
+ message: "Tool schema is not valid json_schema.",
64
+ traceAt,
65
+ context: {
66
+ schemaType: "json_schema",
67
+ attempts
68
+ }
69
+ }));
70
+ };
71
+ const getStandardRecord = (schema) => {
72
+ const standard = schema?.["~standard"];
73
+ return standard && typeof standard === "object" ? standard : void 0;
74
+ };
75
+ const hasStandardValidate = (schema) => typeof getStandardRecord(schema)?.validate === "function";
76
+ const hasStandardJsonSchema = (schema) => {
77
+ const jsonSchema = getStandardRecord(schema)?.jsonSchema;
78
+ return !!jsonSchema && typeof jsonSchema === "object" && typeof jsonSchema.input === "function";
79
+ };
80
+ const resolveToJsonSchema = (schema) => {
81
+ const traceAt = "core.schema.resolveToJsonSchema";
82
+ const standard = getStandardRecord(schema);
83
+ if (hasStandardJsonSchema(schema)) {
84
+ const cachedSchema = resolvedStandardJsonSchemaCache.get(schema);
85
+ if (cachedSchema) return ok(cachedSchema);
86
+ const attempts = [];
87
+ for (const target of ["draft-07", "draft-2020-12"]) try {
88
+ const resolvedSchema = schema["~standard"].jsonSchema.input({ target });
89
+ resolvedStandardJsonSchemaCache.set(schema, resolvedSchema);
90
+ return ok(resolvedSchema);
91
+ } catch (cause) {
92
+ attempts.push({
93
+ target,
94
+ error: cause instanceof Error ? cause.message : String(cause)
95
+ });
96
+ }
97
+ return err(createSchemaError({
98
+ message: "Tool schema could not be resolved to json_schema.",
99
+ traceAt,
100
+ context: {
101
+ schemaType: "standard_schema",
102
+ standardVendor: schema["~standard"].vendor,
103
+ attempts
104
+ }
105
+ }));
106
+ }
107
+ if (standard !== void 0) return err(createSchemaError({
108
+ message: "Tool schema must be raw json_schema or a Standard JSON Schema with `~standard.jsonSchema.input()`.",
109
+ traceAt,
110
+ context: {
111
+ schemaType: "standard_schema",
112
+ standardVendor: typeof standard.vendor === "string" ? standard.vendor : void 0,
113
+ supportsJsonSchema: false
114
+ }
115
+ }));
116
+ if (!schema || typeof schema !== "object" || Array.isArray(schema)) return err(createSchemaError({
117
+ message: "Tool schema must be raw json_schema or a Standard JSON Schema with `~standard.jsonSchema.input()`.",
118
+ traceAt,
119
+ context: { schemaType: "json_schema" }
120
+ }));
121
+ const jsonSchema = schema;
122
+ const compiled = compileJsonSchema(jsonSchema, traceAt);
123
+ if (compiled.isErr()) return err(compiled.error);
124
+ return ok(jsonSchema);
125
+ };
126
+ const validateInput = async (schema, data, options) => {
127
+ const invalidMessage = options?.invalidMessage ?? "The provided data is invalid according to schema.";
128
+ if (hasStandardValidate(schema)) try {
129
+ const result = await schema["~standard"].validate(data);
130
+ if (result.issues && result.issues.length > 0) return err(createSchemaError({
131
+ message: invalidMessage,
132
+ traceAt: "core.schema.validateInput",
133
+ context: { issuesCount: result.issues.length },
134
+ issues: result.issues
135
+ }));
136
+ return ok("value" in result ? result.value : data);
137
+ } catch (cause) {
138
+ return err(createSchemaError({
139
+ message: "Schema validation failed.",
140
+ traceAt: "core.schema.validateInput",
141
+ cause
142
+ }));
143
+ }
144
+ const resolved = resolveToJsonSchema(schema);
145
+ if (resolved.isErr()) return err(resolved.error);
146
+ const compiled = compileJsonSchema(resolved.value, "core.schema.validateInput");
147
+ if (compiled.isErr()) return err(compiled.error);
148
+ try {
149
+ if (!compiled.value(data)) return err(createSchemaError({
150
+ message: invalidMessage,
151
+ traceAt: "core.schema.validateInput",
152
+ context: { issuesCount: compiled.value.errors?.length ?? 0 },
153
+ issues: compiled.value.errors ?? []
154
+ }));
155
+ return ok(data);
156
+ } catch (cause) {
157
+ return err(createSchemaError({
158
+ message: "Schema validation failed.",
159
+ traceAt: "core.schema.validateInput",
160
+ cause
161
+ }));
162
+ }
163
+ };
164
+
165
+ //#endregion
166
+ export { resolveToJsonSchema, validateInput };
167
+ //# sourceMappingURL=resolve-json-schema.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-json-schema.mjs","names":[],"sources":["../../src/schema/resolve-json-schema.ts"],"sourcesContent":["import { BetterAgentError } from \"@better-agent/shared/errors\";\nimport { type Result, err, ok } from \"@better-agent/shared/neverthrow\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport Ajv from \"ajv\";\nimport type { ValidateFunction } from \"ajv\";\nimport Ajv2020 from \"ajv/dist/2020.js\";\nimport type { ResolvableSchema, ValidatableSchema } from \"./types\";\n\ntype JsonSchemaTarget = \"draft-07\" | \"draft-2020-12\";\n\nconst ajvDraft7 = new Ajv({\n allErrors: true,\n logger: false,\n});\n\nconst ajvDraft2020 = new Ajv2020({\n allErrors: true,\n logger: false,\n});\n\nconst compiledJsonSchemaCache = new WeakMap<Record<string, unknown>, ValidateFunction>();\nconst resolvedStandardJsonSchemaCache = new WeakMap<object, Record<string, unknown>>();\n\nconst createSchemaError = (params: {\n message: string;\n traceAt: string;\n context?: Record<string, unknown>;\n issues?: readonly unknown[] | null;\n cause?: unknown;\n}): BetterAgentError =>\n params.cause\n ? BetterAgentError.wrap({\n err: params.cause,\n message: params.message,\n opts: {\n code: \"VALIDATION_FAILED\",\n context: {\n ...(params.context ?? {}),\n ...(params.issues !== undefined ? { issues: params.issues } : {}),\n },\n trace: [{ at: params.traceAt }],\n },\n })\n : BetterAgentError.fromCode(\"VALIDATION_FAILED\", params.message, {\n context: {\n ...(params.context ?? {}),\n ...(params.issues !== undefined ? { issues: params.issues } : {}),\n },\n trace: [{ at: params.traceAt }],\n });\n\nconst compileJsonSchema = (\n schema: Record<string, unknown>,\n traceAt: string,\n): Result<ValidateFunction, BetterAgentError> => {\n const cachedValidator = compiledJsonSchemaCache.get(schema);\n if (cachedValidator) {\n return ok(cachedValidator);\n }\n\n const schemaId = schema.$schema;\n const targets: JsonSchemaTarget[] = [];\n\n if (typeof schemaId === \"string\") {\n if (schemaId.includes(\"draft-07\")) {\n targets.push(\"draft-07\");\n } else if (schemaId.includes(\"draft/2020-12\")) {\n targets.push(\"draft-2020-12\");\n } else {\n return err(\n createSchemaError({\n message: \"Tool schema uses an unsupported json_schema dialect.\",\n traceAt,\n context: {\n schemaType: \"json_schema\",\n schemaDialect: schemaId,\n },\n }),\n );\n }\n } else {\n targets.push(\"draft-07\", \"draft-2020-12\");\n }\n\n const attempts: Array<Record<string, unknown>> = [];\n\n for (const target of targets) {\n try {\n const validator =\n target === \"draft-2020-12\"\n ? ajvDraft2020.compile(schema)\n : ajvDraft7.compile(schema);\n compiledJsonSchemaCache.set(schema, validator);\n return ok(validator);\n } catch (cause) {\n attempts.push({\n target,\n error: cause instanceof Error ? cause.message : String(cause),\n });\n }\n }\n\n return err(\n createSchemaError({\n message: \"Tool schema is not valid json_schema.\",\n traceAt,\n context: {\n schemaType: \"json_schema\",\n attempts,\n },\n }),\n );\n};\n\nconst getStandardRecord = (schema: unknown): Record<string, unknown> | undefined => {\n const standard = (schema as { \"~standard\"?: unknown })?.[\"~standard\"];\n return standard && typeof standard === \"object\"\n ? (standard as Record<string, unknown>)\n : undefined;\n};\n\nconst hasStandardValidate = (schema: unknown): schema is StandardSchemaV1 =>\n typeof getStandardRecord(schema)?.validate === \"function\";\n\nconst hasStandardJsonSchema = (\n schema: unknown,\n): schema is {\n \"~standard\": {\n vendor?: string;\n jsonSchema: {\n input: (options: { target: JsonSchemaTarget }) => Record<string, unknown>;\n };\n };\n} => {\n const jsonSchema = getStandardRecord(schema)?.jsonSchema;\n return (\n !!jsonSchema &&\n typeof jsonSchema === \"object\" &&\n typeof (jsonSchema as { input?: unknown }).input === \"function\"\n );\n};\n\nexport const resolveToJsonSchema = (\n schema: ResolvableSchema,\n): Result<Record<string, unknown>, BetterAgentError> => {\n const traceAt = \"core.schema.resolveToJsonSchema\";\n const standard = getStandardRecord(schema);\n\n if (hasStandardJsonSchema(schema)) {\n const cachedSchema = resolvedStandardJsonSchemaCache.get(schema);\n if (cachedSchema) {\n return ok(cachedSchema);\n }\n\n const attempts: Array<Record<string, unknown>> = [];\n\n for (const target of [\"draft-07\", \"draft-2020-12\"] as const) {\n try {\n const resolvedSchema = schema[\"~standard\"].jsonSchema.input({ target });\n resolvedStandardJsonSchemaCache.set(schema, resolvedSchema);\n return ok(resolvedSchema);\n } catch (cause) {\n attempts.push({\n target,\n error: cause instanceof Error ? cause.message : String(cause),\n });\n }\n }\n\n return err(\n createSchemaError({\n message: \"Tool schema could not be resolved to json_schema.\",\n traceAt,\n context: {\n schemaType: \"standard_schema\",\n standardVendor: schema[\"~standard\"].vendor,\n attempts,\n },\n }),\n );\n }\n\n if (standard !== undefined) {\n return err(\n createSchemaError({\n message:\n \"Tool schema must be raw json_schema or a Standard JSON Schema with `~standard.jsonSchema.input()`.\",\n traceAt,\n context: {\n schemaType: \"standard_schema\",\n standardVendor:\n typeof standard.vendor === \"string\" ? standard.vendor : undefined,\n supportsJsonSchema: false,\n },\n }),\n );\n }\n\n if (!schema || typeof schema !== \"object\" || Array.isArray(schema)) {\n return err(\n createSchemaError({\n message:\n \"Tool schema must be raw json_schema or a Standard JSON Schema with `~standard.jsonSchema.input()`.\",\n traceAt,\n context: {\n schemaType: \"json_schema\",\n },\n }),\n );\n }\n\n const jsonSchema = schema as Record<string, unknown>;\n const compiled = compileJsonSchema(jsonSchema, traceAt);\n if (compiled.isErr()) {\n return err(compiled.error);\n }\n\n return ok(jsonSchema);\n};\n\nexport const validateInput = async <T>(\n schema: ValidatableSchema,\n data: unknown,\n options?: {\n invalidMessage?: string;\n },\n): Promise<Result<T, BetterAgentError>> => {\n const invalidMessage =\n options?.invalidMessage ?? \"The provided data is invalid according to schema.\";\n\n if (hasStandardValidate(schema)) {\n try {\n const result = await schema[\"~standard\"].validate(data);\n\n if (result.issues && result.issues.length > 0) {\n return err(\n createSchemaError({\n message: invalidMessage,\n traceAt: \"core.schema.validateInput\",\n context: {\n issuesCount: result.issues.length,\n },\n issues: result.issues,\n }),\n );\n }\n\n return ok((\"value\" in result ? result.value : data) as T);\n } catch (cause) {\n return err(\n createSchemaError({\n message: \"Schema validation failed.\",\n traceAt: \"core.schema.validateInput\",\n cause,\n }),\n );\n }\n }\n\n const resolved = resolveToJsonSchema(schema);\n if (resolved.isErr()) {\n return err(resolved.error);\n }\n\n const compiled = compileJsonSchema(resolved.value, \"core.schema.validateInput\");\n if (compiled.isErr()) {\n return err(compiled.error);\n }\n\n try {\n const valid = compiled.value(data);\n if (!valid) {\n return err(\n createSchemaError({\n message: invalidMessage,\n traceAt: \"core.schema.validateInput\",\n context: {\n issuesCount: compiled.value.errors?.length ?? 0,\n },\n issues: compiled.value.errors ?? [],\n }),\n );\n }\n\n return ok(data as T);\n } catch (cause) {\n return err(\n createSchemaError({\n message: \"Schema validation failed.\",\n traceAt: \"core.schema.validateInput\",\n cause,\n }),\n );\n }\n};\n"],"mappings":";;;;;;AAUA,MAAM,YAAY,IAAI,IAAI;CACtB,WAAW;CACX,QAAQ;CACX,CAAC;AAEF,MAAM,eAAe,IAAI,QAAQ;CAC7B,WAAW;CACX,QAAQ;CACX,CAAC;AAEF,MAAM,0CAA0B,IAAI,SAAoD;AACxF,MAAM,kDAAkC,IAAI,SAA0C;AAEtF,MAAM,qBAAqB,WAOvB,OAAO,QACD,iBAAiB,KAAK;CAClB,KAAK,OAAO;CACZ,SAAS,OAAO;CAChB,MAAM;EACF,MAAM;EACN,SAAS;GACL,GAAI,OAAO,WAAW,EAAE;GACxB,GAAI,OAAO,WAAW,SAAY,EAAE,QAAQ,OAAO,QAAQ,GAAG,EAAE;GACnE;EACD,OAAO,CAAC,EAAE,IAAI,OAAO,SAAS,CAAC;EAClC;CACJ,CAAC,GACF,iBAAiB,SAAS,qBAAqB,OAAO,SAAS;CAC3D,SAAS;EACL,GAAI,OAAO,WAAW,EAAE;EACxB,GAAI,OAAO,WAAW,SAAY,EAAE,QAAQ,OAAO,QAAQ,GAAG,EAAE;EACnE;CACD,OAAO,CAAC,EAAE,IAAI,OAAO,SAAS,CAAC;CAClC,CAAC;AAEZ,MAAM,qBACF,QACA,YAC6C;CAC7C,MAAM,kBAAkB,wBAAwB,IAAI,OAAO;AAC3D,KAAI,gBACA,QAAO,GAAG,gBAAgB;CAG9B,MAAM,WAAW,OAAO;CACxB,MAAM,UAA8B,EAAE;AAEtC,KAAI,OAAO,aAAa,SACpB,KAAI,SAAS,SAAS,WAAW,CAC7B,SAAQ,KAAK,WAAW;UACjB,SAAS,SAAS,gBAAgB,CACzC,SAAQ,KAAK,gBAAgB;KAE7B,QAAO,IACH,kBAAkB;EACd,SAAS;EACT;EACA,SAAS;GACL,YAAY;GACZ,eAAe;GAClB;EACJ,CAAC,CACL;KAGL,SAAQ,KAAK,YAAY,gBAAgB;CAG7C,MAAM,WAA2C,EAAE;AAEnD,MAAK,MAAM,UAAU,QACjB,KAAI;EACA,MAAM,YACF,WAAW,kBACL,aAAa,QAAQ,OAAO,GAC5B,UAAU,QAAQ,OAAO;AACnC,0BAAwB,IAAI,QAAQ,UAAU;AAC9C,SAAO,GAAG,UAAU;UACf,OAAO;AACZ,WAAS,KAAK;GACV;GACA,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;GAChE,CAAC;;AAIV,QAAO,IACH,kBAAkB;EACd,SAAS;EACT;EACA,SAAS;GACL,YAAY;GACZ;GACH;EACJ,CAAC,CACL;;AAGL,MAAM,qBAAqB,WAAyD;CAChF,MAAM,WAAY,SAAuC;AACzD,QAAO,YAAY,OAAO,aAAa,WAChC,WACD;;AAGV,MAAM,uBAAuB,WACzB,OAAO,kBAAkB,OAAO,EAAE,aAAa;AAEnD,MAAM,yBACF,WAQC;CACD,MAAM,aAAa,kBAAkB,OAAO,EAAE;AAC9C,QACI,CAAC,CAAC,cACF,OAAO,eAAe,YACtB,OAAQ,WAAmC,UAAU;;AAI7D,MAAa,uBACT,WACoD;CACpD,MAAM,UAAU;CAChB,MAAM,WAAW,kBAAkB,OAAO;AAE1C,KAAI,sBAAsB,OAAO,EAAE;EAC/B,MAAM,eAAe,gCAAgC,IAAI,OAAO;AAChE,MAAI,aACA,QAAO,GAAG,aAAa;EAG3B,MAAM,WAA2C,EAAE;AAEnD,OAAK,MAAM,UAAU,CAAC,YAAY,gBAAgB,CAC9C,KAAI;GACA,MAAM,iBAAiB,OAAO,aAAa,WAAW,MAAM,EAAE,QAAQ,CAAC;AACvE,mCAAgC,IAAI,QAAQ,eAAe;AAC3D,UAAO,GAAG,eAAe;WACpB,OAAO;AACZ,YAAS,KAAK;IACV;IACA,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;IAChE,CAAC;;AAIV,SAAO,IACH,kBAAkB;GACd,SAAS;GACT;GACA,SAAS;IACL,YAAY;IACZ,gBAAgB,OAAO,aAAa;IACpC;IACH;GACJ,CAAC,CACL;;AAGL,KAAI,aAAa,OACb,QAAO,IACH,kBAAkB;EACd,SACI;EACJ;EACA,SAAS;GACL,YAAY;GACZ,gBACI,OAAO,SAAS,WAAW,WAAW,SAAS,SAAS;GAC5D,oBAAoB;GACvB;EACJ,CAAC,CACL;AAGL,KAAI,CAAC,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,OAAO,CAC9D,QAAO,IACH,kBAAkB;EACd,SACI;EACJ;EACA,SAAS,EACL,YAAY,eACf;EACJ,CAAC,CACL;CAGL,MAAM,aAAa;CACnB,MAAM,WAAW,kBAAkB,YAAY,QAAQ;AACvD,KAAI,SAAS,OAAO,CAChB,QAAO,IAAI,SAAS,MAAM;AAG9B,QAAO,GAAG,WAAW;;AAGzB,MAAa,gBAAgB,OACzB,QACA,MACA,YAGuC;CACvC,MAAM,iBACF,SAAS,kBAAkB;AAE/B,KAAI,oBAAoB,OAAO,CAC3B,KAAI;EACA,MAAM,SAAS,MAAM,OAAO,aAAa,SAAS,KAAK;AAEvD,MAAI,OAAO,UAAU,OAAO,OAAO,SAAS,EACxC,QAAO,IACH,kBAAkB;GACd,SAAS;GACT,SAAS;GACT,SAAS,EACL,aAAa,OAAO,OAAO,QAC9B;GACD,QAAQ,OAAO;GAClB,CAAC,CACL;AAGL,SAAO,GAAI,WAAW,SAAS,OAAO,QAAQ,KAAW;UACpD,OAAO;AACZ,SAAO,IACH,kBAAkB;GACd,SAAS;GACT,SAAS;GACT;GACH,CAAC,CACL;;CAIT,MAAM,WAAW,oBAAoB,OAAO;AAC5C,KAAI,SAAS,OAAO,CAChB,QAAO,IAAI,SAAS,MAAM;CAG9B,MAAM,WAAW,kBAAkB,SAAS,OAAO,4BAA4B;AAC/E,KAAI,SAAS,OAAO,CAChB,QAAO,IAAI,SAAS,MAAM;AAG9B,KAAI;AAEA,MAAI,CADU,SAAS,MAAM,KAAK,CAE9B,QAAO,IACH,kBAAkB;GACd,SAAS;GACT,SAAS;GACT,SAAS,EACL,aAAa,SAAS,MAAM,QAAQ,UAAU,GACjD;GACD,QAAQ,SAAS,MAAM,UAAU,EAAE;GACtC,CAAC,CACL;AAGL,SAAO,GAAG,KAAU;UACf,OAAO;AACZ,SAAO,IACH,kBAAkB;GACd,SAAS;GACT,SAAS;GACT;GACH,CAAC,CACL"}
@@ -0,0 +1,27 @@
1
+ import { StandardJSONSchemaV1, StandardSchemaV1, StandardTypedV1 } from "@standard-schema/spec";
2
+ import { FromSchema } from "json-schema-to-ts";
3
+
4
+ //#region src/schema/types.d.ts
5
+ /** Any Standard Schema v1 instance. */
6
+ type AnyStandardSchemaV1 = StandardSchemaV1<any, any>;
7
+ /** Standard Schema v1 typed schema. */
8
+ type StandardSchema<I = unknown, O = I> = StandardTypedV1<I, O>;
9
+ /** Schema inputs that can be resolved to JSON Schema. */
10
+ type ResolvableSchema<I = unknown, O = I> = StandardJSONSchemaV1<I, O> | Record<string, unknown>;
11
+ /** Schema inputs that can be validated at runtime. */
12
+ type ValidatableSchema<I = unknown, O = I> = StandardSchemaV1<I, O> | ResolvableSchema<I, O>;
13
+ /** Infers the input type from a Standard Schema v1 typed schema. */
14
+ type InferStandardInput<TSchema> = TSchema extends {
15
+ "~standard"?: {
16
+ types?: {
17
+ input?: infer I;
18
+ };
19
+ };
20
+ } ? I : never;
21
+ /**
22
+ * Infers the input type from either a Standard Schema v1 typed schema or a JSON Schema object.
23
+ */
24
+ type InferSchemaInput<TSchema> = [InferStandardInput<TSchema>] extends [never] ? TSchema extends Record<string, unknown> ? FromSchema<TSchema> : unknown : InferStandardInput<TSchema>;
25
+ //#endregion
26
+ export { AnyStandardSchemaV1, InferSchemaInput, InferStandardInput, ResolvableSchema, StandardSchema, ValidatableSchema };
27
+ //# sourceMappingURL=types.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../../src/schema/types.ts"],"mappings":";;;;;KASY,mBAAA,GAAsB,gBAAA;AAAlC;AAAA,KAGY,cAAA,kBAAgC,CAAA,IAAK,eAAA,CAAgB,CAAA,EAAG,CAAA;;KAGxD,gBAAA,kBAAkC,CAAA,IACxC,oBAAA,CAAqB,CAAA,EAAG,CAAA,IACxB,MAAA;;KAGM,iBAAA,kBAAmC,CAAA,IAAK,gBAAA,CAAiB,CAAA,EAAG,CAAA,IAAK,gBAAA,CAAiB,CAAA,EAAG,CAAA;;KAGrF,kBAAA,YAA8B,OAAA;EACtC,WAAA;IAAgB,KAAA;MAAU,KAAA;IAAA;EAAA;AAAA,IAExB,CAAA;;;;KAMM,gBAAA,aAA6B,kBAAA,CAAmB,OAAA,qBACtD,OAAA,SAAgB,MAAA,oBACZ,UAAA,CAAW,OAAA,cAEf,kBAAA,CAAmB,OAAA"}
@@ -0,0 +1,21 @@
1
+ import { BetterAgentServer, CreateServerConfig } from "./types.mjs";
2
+
3
+ //#region src/server/create-server.d.ts
4
+ /**
5
+ * Creates a built-in HTTP server.
6
+ *
7
+ * When `secret` is set, non-public routes require `Authorization: Bearer <secret>`.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const server = createServer({
12
+ * runtime,
13
+ * secret: "dev-secret",
14
+ * basePath: "/api",
15
+ * });
16
+ * ```
17
+ */
18
+ declare function createServer(config: CreateServerConfig): BetterAgentServer;
19
+ //#endregion
20
+ export { createServer };
21
+ //# sourceMappingURL=create-server.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-server.d.mts","names":[],"sources":["../../src/server/create-server.ts"],"mappings":";;;;;AAwBA;;;;;;;;;;;;iBAAgB,YAAA,CAAa,MAAA,EAAQ,kBAAA,GAAqB,iBAAA"}
@@ -0,0 +1,107 @@
1
+ import { createRouter } from "../api.mjs";
2
+ import { jsonErrorResponse, methodNotAllowedResponse, notFoundResponse, toServerErrorResponse } from "./http.mjs";
3
+ import { createServerRoutes, runPluginGuards } from "./routes.mjs";
4
+
5
+ //#region src/server/create-server.ts
6
+ /**
7
+ * Creates a built-in HTTP server.
8
+ *
9
+ * When `secret` is set, non-public routes require `Authorization: Bearer <secret>`.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * const server = createServer({
14
+ * runtime,
15
+ * secret: "dev-secret",
16
+ * basePath: "/api",
17
+ * });
18
+ * ```
19
+ */
20
+ function createServer(config) {
21
+ const sseHeartbeatMs = config.advanced?.sseHeartbeatMs;
22
+ const onRequestDisconnect = config.advanced?.onRequestDisconnect ?? (config.runtime.streamLifecycle === "detached" ? "continue" : "abort");
23
+ const basePath = typeof config.basePath === "string" && config.basePath.length > 0 ? config.basePath.replace(/\/$/, "") : "";
24
+ const deps = {
25
+ runtime: config.runtime,
26
+ pluginRuntime: config.pluginRuntime ?? null,
27
+ sseHeartbeatMs,
28
+ onRequestDisconnect
29
+ };
30
+ const router = createRouter(createServerRoutes(deps));
31
+ const getHeader = (headers, name) => {
32
+ if (!headers || typeof headers !== "object") return null;
33
+ if ("get" in headers && typeof headers.get === "function") {
34
+ const value = headers.get(name);
35
+ return typeof value === "string" ? value : null;
36
+ }
37
+ const record = headers;
38
+ const direct = record[name] ?? record[name.toLowerCase()] ?? record[name.toUpperCase()];
39
+ return typeof direct === "string" ? direct : null;
40
+ };
41
+ const toAbsoluteUrlString = (request) => {
42
+ try {
43
+ return new URL(request.url).toString();
44
+ } catch {
45
+ const host = getHeader(request.headers, "x-forwarded-host") ?? getHeader(request.headers, "host") ?? "localhost";
46
+ const protocol = getHeader(request.headers, "x-forwarded-proto") === "https" ? "https" : "http";
47
+ return new URL(request.url, `${protocol}://${host}`).toString();
48
+ }
49
+ };
50
+ const normalizeRequest = (request) => {
51
+ const hasHeadersGet = typeof request.headers?.get === "function";
52
+ const hasAbsoluteUrl = (() => {
53
+ try {
54
+ new URL(request.url);
55
+ return true;
56
+ } catch {
57
+ return false;
58
+ }
59
+ })();
60
+ if (request instanceof Request && hasHeadersGet && hasAbsoluteUrl) return request;
61
+ return new Request(toAbsoluteUrlString(request), {
62
+ method: request.method,
63
+ headers: request.headers,
64
+ body: request.method === "GET" || request.method === "HEAD" ? void 0 : request.body,
65
+ ...request.method !== "GET" && request.method !== "HEAD" && request.body != null ? { duplex: "half" } : {},
66
+ signal: request.signal
67
+ });
68
+ };
69
+ return { async handle(request) {
70
+ try {
71
+ const normalizedRequest = normalizeRequest(request);
72
+ const url = new URL(normalizedRequest.url);
73
+ const path = !basePath || !url.pathname.startsWith(basePath) ? url.pathname : url.pathname.length > basePath.length && url.pathname[basePath.length] !== "/" ? url.pathname : url.pathname.slice(basePath.length) || "/";
74
+ const match = router.match(normalizedRequest.method, path);
75
+ if (!match) {
76
+ const pathMatch = router.matchPath(path);
77
+ if (pathMatch) return methodNotAllowedResponse(pathMatch.methods);
78
+ return notFoundResponse();
79
+ }
80
+ if (config.secret && match.route.public !== true) {
81
+ if (normalizedRequest.headers.get("authorization") !== `Bearer ${config.secret}`) return jsonErrorResponse({
82
+ code: "UNAUTHORIZED",
83
+ message: "Missing or invalid bearer token.",
84
+ status: 401
85
+ }, { headers: { "www-authenticate": "Bearer" } });
86
+ }
87
+ const guardResult = await runPluginGuards({
88
+ pluginRuntime: deps.pluginRuntime,
89
+ match,
90
+ request: normalizedRequest
91
+ });
92
+ if (guardResult) return guardResult;
93
+ return await match.route.handler({
94
+ request: normalizedRequest,
95
+ path,
96
+ params: match.params,
97
+ query: url.searchParams
98
+ });
99
+ } catch (error) {
100
+ return toServerErrorResponse(error);
101
+ }
102
+ } };
103
+ }
104
+
105
+ //#endregion
106
+ export { createServer };
107
+ //# sourceMappingURL=create-server.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-server.mjs","names":[],"sources":["../../src/server/create-server.ts"],"sourcesContent":["import { type HttpMethod, createRouter } from \"../api\";\nimport {\n jsonErrorResponse,\n methodNotAllowedResponse,\n notFoundResponse,\n toServerErrorResponse,\n} from \"./http\";\nimport { createServerRoutes, runPluginGuards } from \"./routes\";\nimport type { BetterAgentServer, CreateServerConfig } from \"./types\";\n\n/**\n * Creates a built-in HTTP server.\n *\n * When `secret` is set, non-public routes require `Authorization: Bearer <secret>`.\n *\n * @example\n * ```ts\n * const server = createServer({\n * runtime,\n * secret: \"dev-secret\",\n * basePath: \"/api\",\n * });\n * ```\n */\nexport function createServer(config: CreateServerConfig): BetterAgentServer {\n const sseHeartbeatMs = config.advanced?.sseHeartbeatMs;\n const onRequestDisconnect =\n config.advanced?.onRequestDisconnect ??\n (config.runtime.streamLifecycle === \"detached\" ? \"continue\" : \"abort\");\n const basePath =\n typeof config.basePath === \"string\" && config.basePath.length > 0\n ? config.basePath.replace(/\\/$/, \"\")\n : \"\";\n\n const deps = {\n runtime: config.runtime,\n pluginRuntime: config.pluginRuntime ?? null,\n sseHeartbeatMs,\n onRequestDisconnect,\n };\n const routes = createServerRoutes(deps);\n const router = createRouter(routes);\n\n // Normalize incoming request-like inputs (objects or path-only URLs) into a standard Fetch Request so downstream handling can rely on consistent Request semantics.\n const getHeader = (headers: unknown, name: string): string | null => {\n if (!headers || typeof headers !== \"object\") {\n return null;\n }\n\n if (\"get\" in headers && typeof headers.get === \"function\") {\n const value = headers.get(name);\n return typeof value === \"string\" ? value : null;\n }\n\n const record = headers as Record<string, unknown>;\n const direct = record[name] ?? record[name.toLowerCase()] ?? record[name.toUpperCase()];\n return typeof direct === \"string\" ? direct : null;\n };\n\n const toAbsoluteUrlString = (request: Request): string => {\n try {\n return new URL(request.url).toString();\n } catch {\n // Recover relative URLs by reconstructing an origin from forwarded or host headers.\n const host =\n getHeader(request.headers, \"x-forwarded-host\") ??\n getHeader(request.headers, \"host\") ??\n \"localhost\";\n const protocol =\n getHeader(request.headers, \"x-forwarded-proto\") === \"https\" ? \"https\" : \"http\";\n return new URL(request.url, `${protocol}://${host}`).toString();\n }\n };\n\n const normalizeRequest = (request: Request): Request => {\n const hasHeadersGet = typeof request.headers?.get === \"function\";\n const hasAbsoluteUrl = (() => {\n try {\n void new URL(request.url);\n return true;\n } catch {\n return false;\n }\n })();\n\n if (request instanceof Request && hasHeadersGet && hasAbsoluteUrl) {\n return request;\n }\n\n return new Request(toAbsoluteUrlString(request), {\n method: request.method,\n headers: request.headers as HeadersInit | undefined,\n body:\n request.method === \"GET\" || request.method === \"HEAD\"\n ? undefined\n : (request as { body?: BodyInit | null }).body,\n ...((request.method !== \"GET\" &&\n request.method !== \"HEAD\" &&\n (request as { body?: BodyInit | null }).body != null\n ? { duplex: \"half\" }\n : {}) as { duplex?: \"half\" }),\n signal: request.signal,\n });\n };\n\n return {\n async handle(request) {\n try {\n const normalizedRequest = normalizeRequest(request);\n const url = new URL(normalizedRequest.url);\n // Normalize pathname by removing basePath only if it’s a true path-segment prefix (not partial like \"/app\" vs \"/apple\")\n const path =\n !basePath || !url.pathname.startsWith(basePath)\n ? url.pathname\n : url.pathname.length > basePath.length &&\n url.pathname[basePath.length] !== \"/\"\n ? url.pathname\n : url.pathname.slice(basePath.length) || \"/\";\n\n const match = router.match(normalizedRequest.method as HttpMethod, path);\n if (!match) {\n const pathMatch = router.matchPath(path);\n if (pathMatch) {\n return methodNotAllowedResponse(pathMatch.methods);\n }\n\n return notFoundResponse();\n }\n\n // Built-in bearer auth is skipped only for routes explicitly marked public.\n if (config.secret && match.route.public !== true) {\n if (\n normalizedRequest.headers.get(\"authorization\") !== `Bearer ${config.secret}`\n ) {\n return jsonErrorResponse(\n {\n code: \"UNAUTHORIZED\",\n message: \"Missing or invalid bearer token.\",\n status: 401,\n },\n {\n headers: {\n \"www-authenticate\": \"Bearer\",\n },\n },\n );\n }\n }\n\n const guardResult = await runPluginGuards({\n pluginRuntime: deps.pluginRuntime,\n match,\n request: normalizedRequest,\n });\n if (guardResult) {\n return guardResult;\n }\n\n return await match.route.handler({\n request: normalizedRequest,\n path,\n params: match.params,\n query: url.searchParams,\n });\n } catch (error) {\n return toServerErrorResponse(error);\n }\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAwBA,SAAgB,aAAa,QAA+C;CACxE,MAAM,iBAAiB,OAAO,UAAU;CACxC,MAAM,sBACF,OAAO,UAAU,wBAChB,OAAO,QAAQ,oBAAoB,aAAa,aAAa;CAClE,MAAM,WACF,OAAO,OAAO,aAAa,YAAY,OAAO,SAAS,SAAS,IAC1D,OAAO,SAAS,QAAQ,OAAO,GAAG,GAClC;CAEV,MAAM,OAAO;EACT,SAAS,OAAO;EAChB,eAAe,OAAO,iBAAiB;EACvC;EACA;EACH;CAED,MAAM,SAAS,aADA,mBAAmB,KAAK,CACJ;CAGnC,MAAM,aAAa,SAAkB,SAAgC;AACjE,MAAI,CAAC,WAAW,OAAO,YAAY,SAC/B,QAAO;AAGX,MAAI,SAAS,WAAW,OAAO,QAAQ,QAAQ,YAAY;GACvD,MAAM,QAAQ,QAAQ,IAAI,KAAK;AAC/B,UAAO,OAAO,UAAU,WAAW,QAAQ;;EAG/C,MAAM,SAAS;EACf,MAAM,SAAS,OAAO,SAAS,OAAO,KAAK,aAAa,KAAK,OAAO,KAAK,aAAa;AACtF,SAAO,OAAO,WAAW,WAAW,SAAS;;CAGjD,MAAM,uBAAuB,YAA6B;AACtD,MAAI;AACA,UAAO,IAAI,IAAI,QAAQ,IAAI,CAAC,UAAU;UAClC;GAEJ,MAAM,OACF,UAAU,QAAQ,SAAS,mBAAmB,IAC9C,UAAU,QAAQ,SAAS,OAAO,IAClC;GACJ,MAAM,WACF,UAAU,QAAQ,SAAS,oBAAoB,KAAK,UAAU,UAAU;AAC5E,UAAO,IAAI,IAAI,QAAQ,KAAK,GAAG,SAAS,KAAK,OAAO,CAAC,UAAU;;;CAIvE,MAAM,oBAAoB,YAA8B;EACpD,MAAM,gBAAgB,OAAO,QAAQ,SAAS,QAAQ;EACtD,MAAM,wBAAwB;AAC1B,OAAI;AACA,IAAK,IAAI,IAAI,QAAQ,IAAI;AACzB,WAAO;WACH;AACJ,WAAO;;MAEX;AAEJ,MAAI,mBAAmB,WAAW,iBAAiB,eAC/C,QAAO;AAGX,SAAO,IAAI,QAAQ,oBAAoB,QAAQ,EAAE;GAC7C,QAAQ,QAAQ;GAChB,SAAS,QAAQ;GACjB,MACI,QAAQ,WAAW,SAAS,QAAQ,WAAW,SACzC,SACC,QAAuC;GAClD,GAAK,QAAQ,WAAW,SACxB,QAAQ,WAAW,UAClB,QAAuC,QAAQ,OAC1C,EAAE,QAAQ,QAAQ,GAClB,EAAE;GACR,QAAQ,QAAQ;GACnB,CAAC;;AAGN,QAAO,EACH,MAAM,OAAO,SAAS;AAClB,MAAI;GACA,MAAM,oBAAoB,iBAAiB,QAAQ;GACnD,MAAM,MAAM,IAAI,IAAI,kBAAkB,IAAI;GAE1C,MAAM,OACF,CAAC,YAAY,CAAC,IAAI,SAAS,WAAW,SAAS,GACzC,IAAI,WACJ,IAAI,SAAS,SAAS,SAAS,UAC7B,IAAI,SAAS,SAAS,YAAY,MAClC,IAAI,WACJ,IAAI,SAAS,MAAM,SAAS,OAAO,IAAI;GAEnD,MAAM,QAAQ,OAAO,MAAM,kBAAkB,QAAsB,KAAK;AACxE,OAAI,CAAC,OAAO;IACR,MAAM,YAAY,OAAO,UAAU,KAAK;AACxC,QAAI,UACA,QAAO,yBAAyB,UAAU,QAAQ;AAGtD,WAAO,kBAAkB;;AAI7B,OAAI,OAAO,UAAU,MAAM,MAAM,WAAW,MACxC;QACI,kBAAkB,QAAQ,IAAI,gBAAgB,KAAK,UAAU,OAAO,SAEpE,QAAO,kBACH;KACI,MAAM;KACN,SAAS;KACT,QAAQ;KACX,EACD,EACI,SAAS,EACL,oBAAoB,UACvB,EACJ,CACJ;;GAIT,MAAM,cAAc,MAAM,gBAAgB;IACtC,eAAe,KAAK;IACpB;IACA,SAAS;IACZ,CAAC;AACF,OAAI,YACA,QAAO;AAGX,UAAO,MAAM,MAAM,MAAM,QAAQ;IAC7B,SAAS;IACT;IACA,QAAQ,MAAM;IACd,OAAO,IAAI;IACd,CAAC;WACG,OAAO;AACZ,UAAO,sBAAsB,MAAM;;IAG9C"}
@@ -0,0 +1,182 @@
1
+ import { BetterAgentError } from "@better-agent/shared/errors";
2
+ import { isPlainRecord } from "@better-agent/shared/utils";
3
+
4
+ //#region src/server/http.ts
5
+ /**
6
+ * Creates a JSON response.
7
+ */
8
+ const jsonResponse = (body, init) => new Response(JSON.stringify(body), {
9
+ ...init,
10
+ headers: {
11
+ "content-type": "application/json",
12
+ ...init?.headers ?? {}
13
+ }
14
+ });
15
+ /**
16
+ * Creates a `204 No Content` response.
17
+ */
18
+ const noContentResponse = () => new Response(null, { status: 204 });
19
+ /**
20
+ * Creates a `404 Not Found` response.
21
+ */
22
+ const notFoundResponse = (message = "Route not found.") => jsonErrorResponse({
23
+ code: "NOT_FOUND",
24
+ message,
25
+ status: 404
26
+ });
27
+ /**
28
+ * Creates a `405 Method Not Allowed` response.
29
+ */
30
+ const methodNotAllowedResponse = (methods) => jsonErrorResponse({
31
+ code: "METHOD_NOT_ALLOWED",
32
+ message: "Request method is not allowed for this route.",
33
+ status: 405
34
+ }, { headers: { allow: methods.join(", ") } });
35
+ /**
36
+ * Creates one validation issue.
37
+ */
38
+ const toValidationIssue = (message, path = "/") => ({
39
+ message,
40
+ path
41
+ });
42
+ /**
43
+ * Creates a `422 Validation Failed` response.
44
+ */
45
+ const invalidRequest = (issues) => jsonErrorResponse({
46
+ code: "VALIDATION_FAILED",
47
+ message: "Request validation failed.",
48
+ status: 422,
49
+ issues
50
+ });
51
+ /**
52
+ * Creates a JSON error response.
53
+ */
54
+ const jsonErrorResponse = (params, init) => jsonResponse({
55
+ code: params.code,
56
+ message: params.message,
57
+ status: params.status,
58
+ ...params.retryable !== void 0 ? { retryable: params.retryable } : {},
59
+ ...params.issues !== void 0 ? { issues: params.issues } : {},
60
+ ...params.traceId !== void 0 ? { traceId: params.traceId } : {},
61
+ ...params.context !== void 0 ? { context: params.context } : {},
62
+ ...params.trace !== void 0 ? { trace: params.trace } : {}
63
+ }, {
64
+ ...init,
65
+ status: params.status,
66
+ headers: { ...init?.headers ?? {} }
67
+ });
68
+ /**
69
+ * Checks whether the request asked for `text/event-stream`.
70
+ */
71
+ const requestsEventStream = (request) => (request.headers.get("accept") ?? "").includes("text/event-stream");
72
+ /**
73
+ * Creates an SSE response from an async iterable.
74
+ */
75
+ const toSseResponse = (params) => {
76
+ const encoder = new TextEncoder();
77
+ let disconnectHandled = false;
78
+ const handleDisconnect = () => {
79
+ if (disconnectHandled) return;
80
+ disconnectHandled = true;
81
+ params.onDisconnect?.();
82
+ };
83
+ const stream = new ReadableStream({
84
+ async start(controller) {
85
+ const heartbeatMs = params.heartbeatMs ?? 15e3;
86
+ const heartbeat = setInterval(() => {
87
+ try {
88
+ controller.enqueue(encoder.encode(":\n\n"));
89
+ } catch {
90
+ clearInterval(heartbeat);
91
+ }
92
+ }, heartbeatMs);
93
+ const onAbort = () => {
94
+ clearInterval(heartbeat);
95
+ handleDisconnect();
96
+ try {
97
+ controller.close();
98
+ } catch {}
99
+ };
100
+ if (params.signal?.aborted) {
101
+ onAbort();
102
+ return;
103
+ }
104
+ params.signal?.addEventListener("abort", onAbort, { once: true });
105
+ try {
106
+ for await (const event of params.events) {
107
+ if (params.signal?.aborted) break;
108
+ const payload = params.useEventIds && isPlainRecord(event) && typeof event.seq === "number" && Number.isFinite(event.seq) ? `id: ${event.seq}\ndata: ${JSON.stringify(event)}\n\n` : `data: ${JSON.stringify(event)}\n\n`;
109
+ controller.enqueue(encoder.encode(payload));
110
+ }
111
+ } catch (error) {
112
+ const payload = JSON.stringify({
113
+ type: "error",
114
+ message: error instanceof Error ? error.message : "Stream failed"
115
+ });
116
+ controller.enqueue(encoder.encode(`event: error\ndata: ${payload}\n\n`));
117
+ } finally {
118
+ clearInterval(heartbeat);
119
+ params.signal?.removeEventListener("abort", onAbort);
120
+ try {
121
+ controller.close();
122
+ } catch {}
123
+ }
124
+ },
125
+ cancel() {
126
+ handleDisconnect();
127
+ }
128
+ });
129
+ return new Response(stream, { headers: {
130
+ "content-type": "text/event-stream",
131
+ "cache-control": "no-cache",
132
+ ...params.streamId !== void 0 ? { "x-stream-id": params.streamId } : {},
133
+ ...params.runId !== void 0 ? { "x-run-id": params.runId } : {}
134
+ } });
135
+ };
136
+ /**
137
+ * Parses `Last-Event-ID` into an `afterSeq` value.
138
+ */
139
+ const parseAfterFromRequest = (request) => {
140
+ const lastEventId = request.headers.get("last-event-id");
141
+ if (!lastEventId) return;
142
+ const after = Number(lastEventId);
143
+ return Number.isFinite(after) ? after : void 0;
144
+ };
145
+ const normalizeValidationIssues = (issues, fallbackMessage) => {
146
+ if (!Array.isArray(issues)) return [toValidationIssue(fallbackMessage)];
147
+ return issues.map((issue) => isPlainRecord(issue) && typeof issue.message === "string" ? {
148
+ message: issue.message,
149
+ path: typeof issue.path === "string" ? issue.path : typeof issue.instancePath === "string" ? issue.instancePath || "/" : "/"
150
+ } : toValidationIssue(fallbackMessage));
151
+ };
152
+ /**
153
+ * Converts an unknown server error into a public HTTP response.
154
+ */
155
+ const toServerErrorResponse = (error) => {
156
+ const wrapped = error instanceof BetterAgentError ? error : BetterAgentError.wrap({
157
+ err: error,
158
+ message: "Server request failed",
159
+ opts: {
160
+ code: "INTERNAL",
161
+ trace: [{ at: "core.server.handle" }]
162
+ }
163
+ });
164
+ const safeMessage = wrapped.code === "INTERNAL" ? "Server request failed." : wrapped.message;
165
+ const issues = wrapped.code === "VALIDATION_FAILED" ? normalizeValidationIssues(wrapped.context?.issues, wrapped.message) : void 0;
166
+ const safeContext = wrapped.code === "INTERNAL" ? void 0 : wrapped.context;
167
+ const safeTrace = wrapped.code === "INTERNAL" ? void 0 : wrapped.trace;
168
+ return jsonErrorResponse({
169
+ code: String(wrapped.code ?? "INTERNAL"),
170
+ message: safeMessage,
171
+ status: wrapped.status,
172
+ retryable: wrapped.retryable,
173
+ issues,
174
+ traceId: wrapped.traceId,
175
+ context: safeContext,
176
+ trace: safeTrace
177
+ });
178
+ };
179
+
180
+ //#endregion
181
+ export { invalidRequest, jsonErrorResponse, jsonResponse, methodNotAllowedResponse, noContentResponse, notFoundResponse, parseAfterFromRequest, requestsEventStream, toServerErrorResponse, toSseResponse, toValidationIssue };
182
+ //# sourceMappingURL=http.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.mjs","names":[],"sources":["../../src/server/http.ts"],"sourcesContent":["import { BetterAgentError, type BetterAgentErrorTraceFrame } from \"@better-agent/shared/errors\";\nimport { isPlainRecord } from \"@better-agent/shared/utils\";\n\n/**\n * Validation issue returned in HTTP error payloads.\n */\nexport interface ValidationIssue {\n message: string;\n path?: string;\n}\n\n/**\n * Creates a JSON response.\n */\nexport const jsonResponse = (body: unknown, init?: ResponseInit): Response =>\n new Response(JSON.stringify(body), {\n ...init,\n headers: {\n \"content-type\": \"application/json\",\n ...(init?.headers ?? {}),\n },\n });\n\n/**\n * Creates a `204 No Content` response.\n */\nexport const noContentResponse = (): Response => new Response(null, { status: 204 });\n\n/**\n * Creates a `404 Not Found` response.\n */\nexport const notFoundResponse = (message = \"Route not found.\"): Response =>\n jsonErrorResponse({ code: \"NOT_FOUND\", message, status: 404 });\n\n/**\n * Creates a `405 Method Not Allowed` response.\n */\nexport const methodNotAllowedResponse = (methods: string[]): Response =>\n jsonErrorResponse(\n {\n code: \"METHOD_NOT_ALLOWED\",\n message: \"Request method is not allowed for this route.\",\n status: 405,\n },\n {\n headers: {\n allow: methods.join(\", \"),\n },\n },\n );\n\n/**\n * Creates one validation issue.\n */\nexport const toValidationIssue = (message: string, path = \"/\"): ValidationIssue => ({\n message,\n path,\n});\n\n/**\n * Creates a `422 Validation Failed` response.\n */\nexport const invalidRequest = (issues: ValidationIssue[]): Response =>\n jsonErrorResponse({\n code: \"VALIDATION_FAILED\",\n message: \"Request validation failed.\",\n status: 422,\n issues,\n });\n\n/**\n * Creates a JSON error response.\n */\nexport const jsonErrorResponse = (\n params: {\n code: string;\n message: string;\n status: number;\n retryable?: boolean;\n issues?: ValidationIssue[];\n traceId?: string;\n context?: Record<string, unknown>;\n trace?: BetterAgentErrorTraceFrame[];\n },\n init?: ResponseInit,\n): Response =>\n jsonResponse(\n {\n code: params.code,\n message: params.message,\n status: params.status,\n ...(params.retryable !== undefined ? { retryable: params.retryable } : {}),\n ...(params.issues !== undefined ? { issues: params.issues } : {}),\n ...(params.traceId !== undefined ? { traceId: params.traceId } : {}),\n ...(params.context !== undefined ? { context: params.context } : {}),\n ...(params.trace !== undefined ? { trace: params.trace } : {}),\n },\n {\n ...init,\n status: params.status,\n headers: {\n ...(init?.headers ?? {}),\n },\n },\n );\n\n/**\n * Checks whether the request asked for `text/event-stream`.\n */\nexport const requestsEventStream = (request: Request): boolean =>\n (request.headers.get(\"accept\") ?? \"\").includes(\"text/event-stream\");\n\n/**\n * Creates an SSE response from an async iterable.\n */\nexport const toSseResponse = (params: {\n events: AsyncIterable<unknown>;\n streamId?: string;\n runId?: string;\n useEventIds?: boolean;\n signal?: AbortSignal;\n heartbeatMs?: number;\n onDisconnect?: () => void | Promise<void>;\n}): Response => {\n const encoder = new TextEncoder();\n let disconnectHandled = false;\n const handleDisconnect = () => {\n if (disconnectHandled) return;\n disconnectHandled = true;\n void params.onDisconnect?.();\n };\n const stream = new ReadableStream({\n async start(controller) {\n const heartbeatMs = params.heartbeatMs ?? 15000;\n const heartbeat = setInterval(() => {\n try {\n controller.enqueue(encoder.encode(\":\\n\\n\"));\n } catch {\n clearInterval(heartbeat);\n }\n }, heartbeatMs);\n const onAbort = () => {\n clearInterval(heartbeat);\n handleDisconnect();\n try {\n controller.close();\n } catch {}\n };\n\n if (params.signal?.aborted) {\n onAbort();\n return;\n }\n\n params.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n try {\n for await (const event of params.events) {\n if (params.signal?.aborted) {\n break;\n }\n\n const payload =\n params.useEventIds &&\n isPlainRecord(event) &&\n typeof event.seq === \"number\" &&\n Number.isFinite(event.seq)\n ? `id: ${event.seq}\\ndata: ${JSON.stringify(event)}\\n\\n`\n : `data: ${JSON.stringify(event)}\\n\\n`;\n controller.enqueue(encoder.encode(payload));\n }\n } catch (error) {\n const payload = JSON.stringify({\n type: \"error\",\n message: error instanceof Error ? error.message : \"Stream failed\",\n });\n controller.enqueue(encoder.encode(`event: error\\ndata: ${payload}\\n\\n`));\n } finally {\n clearInterval(heartbeat);\n params.signal?.removeEventListener(\"abort\", onAbort);\n try {\n controller.close();\n } catch {}\n }\n },\n cancel() {\n handleDisconnect();\n },\n });\n\n return new Response(stream, {\n headers: {\n \"content-type\": \"text/event-stream\",\n \"cache-control\": \"no-cache\",\n ...(params.streamId !== undefined ? { \"x-stream-id\": params.streamId } : {}),\n ...(params.runId !== undefined ? { \"x-run-id\": params.runId } : {}),\n },\n });\n};\n\n/**\n * Parses `Last-Event-ID` into an `afterSeq` value.\n */\nexport const parseAfterFromRequest = (request: Request): number | undefined => {\n const lastEventId = request.headers.get(\"last-event-id\");\n if (!lastEventId) {\n return undefined;\n }\n\n const after = Number(lastEventId);\n return Number.isFinite(after) ? after : undefined;\n};\n\nconst normalizeValidationIssues = (issues: unknown, fallbackMessage: string): ValidationIssue[] => {\n if (!Array.isArray(issues)) {\n return [toValidationIssue(fallbackMessage)];\n }\n\n return issues.map((issue) =>\n isPlainRecord(issue) && typeof issue.message === \"string\"\n ? {\n message: issue.message,\n path:\n typeof issue.path === \"string\"\n ? issue.path\n : typeof issue.instancePath === \"string\"\n ? issue.instancePath || \"/\"\n : \"/\",\n }\n : toValidationIssue(fallbackMessage),\n );\n};\n\n/**\n * Converts an unknown server error into a public HTTP response.\n */\nexport const toServerErrorResponse = (error: unknown): Response => {\n const wrapped =\n error instanceof BetterAgentError\n ? error\n : BetterAgentError.wrap({\n err: error,\n message: \"Server request failed\",\n opts: {\n code: \"INTERNAL\",\n trace: [{ at: \"core.server.handle\" }],\n },\n });\n\n const safeMessage = wrapped.code === \"INTERNAL\" ? \"Server request failed.\" : wrapped.message;\n const issues =\n wrapped.code === \"VALIDATION_FAILED\"\n ? normalizeValidationIssues(wrapped.context?.issues, wrapped.message)\n : undefined;\n const safeContext = wrapped.code === \"INTERNAL\" ? undefined : wrapped.context;\n const safeTrace = wrapped.code === \"INTERNAL\" ? undefined : wrapped.trace;\n\n return jsonErrorResponse({\n code: String(wrapped.code ?? \"INTERNAL\"),\n message: safeMessage,\n status: wrapped.status,\n retryable: wrapped.retryable,\n issues,\n traceId: wrapped.traceId,\n context: safeContext,\n trace: safeTrace,\n });\n};\n"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { BetterAgentServer, CreateServerConfig } from "./types.mjs";
2
+ import { createServer } from "./create-server.mjs";
3
+ export { type BetterAgentServer, type CreateServerConfig, createServer };
@@ -0,0 +1,3 @@
1
+ import { createServer } from "./create-server.mjs";
2
+
3
+ export { createServer };