@nanobpm/urban 0.87.1 → 0.88.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.
- package/dist/runtime/core/modules/mcp.d.ts +28 -0
- package/dist/runtime/core/modules/mcp.js +3 -3
- package/dist/runtime/core/modules/runtime.gen.js +1 -1
- package/dist/runtime/mcp-conformance.d.ts +49 -0
- package/dist/runtime/mcp-conformance.js +132 -0
- package/package.json +2 -1
- package/src/openapi/consumer-specs/README.md +51 -0
- package/src/openapi/consumer-specs/nano-workforce.openapi.yaml +5050 -0
- package/src/runtime/browser/runtime.browser.js +77 -1
- package/src/runtime/browser/runtime.browser.test.ts +126 -1
- package/src/runtime/core/modules/mcp.ts +3 -3
- package/src/runtime/core/modules/runtime.gen.ts +1 -1
- package/src/runtime/mcp-conformance.test.ts +127 -0
- package/src/runtime/mcp-conformance.ts +199 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type OpenApiDoc, type OpenApiSchema, type OperationInfo } from "../../../openapi/spec.ts";
|
|
1
2
|
import type { AppApi, RuntimeContext } from "../context.ts";
|
|
2
3
|
import type { HttpRequest } from "../host.ts";
|
|
3
4
|
import { type Route } from "../router.ts";
|
|
@@ -64,6 +65,33 @@ export declare function readHeader(headers: Record<string, string | string[] | u
|
|
|
64
65
|
* required is enough to have missing (or whitespace-only) calls rejected rather than silently
|
|
65
66
|
* substituted with an empty string. */
|
|
66
67
|
export declare function missingRequiredArgs(inputSchema: Record<string, unknown>, args: Record<string, unknown>): string[];
|
|
68
|
+
/** The operation's effective request-body schema for classifying a tool-call `body`: P0's resolved,
|
|
69
|
+
* `$ref`-free schema ({@link OperationInfo.requestBodySchemaResolved}, produced by
|
|
70
|
+
* `collectOperations`). As defence in depth, if that metadata is somehow still a bare `$ref` (it
|
|
71
|
+
* should never be after resolution), re-resolve it via {@link resolveSchema} against `doc` so the
|
|
72
|
+
* classification below never keys off an opaque `#/components/...` pointer. */
|
|
73
|
+
export declare function effectiveRequestBodySchema(op: OperationInfo, doc: OpenApiDoc | undefined): OpenApiSchema | undefined;
|
|
74
|
+
/** Whether the operation declares a STRUCTURED (object/array) request body — the shapes the app door
|
|
75
|
+
* expects as a JSON object/array rather than a bare scalar. Classified from the RESOLVED schema so a
|
|
76
|
+
* `$ref`-bodied op (e.g. `previewDeliveryGraph`, whose object `type` is only visible after P0's
|
|
77
|
+
* resolution) is recognized, not merely an inline-`type` object body. */
|
|
78
|
+
export declare function structuredBodyKind(schema: OpenApiSchema | undefined): "object" | "array" | undefined;
|
|
79
|
+
/** Normalize a tool-call `body` argument for FAITHFUL transport (ADR 0067). A client that saw an
|
|
80
|
+
* opaque input schema — or that coerces non-primitive args — may send `body` as a pre-encoded JSON
|
|
81
|
+
* *string* instead of the object/array the operation declares. Left as-is, `toHttpRequest`'s
|
|
82
|
+
* `JSON.stringify` would DOUBLE-encode it into a quoted string and the door would reject it with
|
|
83
|
+
* "expected object, got string". So when the op declares an object/array body and `body` arrives as
|
|
84
|
+
* a string, parse it once so it round-trips as the structured value. A genuine object/array argument
|
|
85
|
+
* passes through untouched (still serialized by the transport). A string that does not parse to the
|
|
86
|
+
* declared shape is a CLEAR tool error naming the expected shape — never a silently double-encoded
|
|
87
|
+
* (and 4xx-rejected) request. */
|
|
88
|
+
export declare function normalizeBodyArg(op: OperationInfo, args: Record<string, unknown>, doc: OpenApiDoc | undefined): {
|
|
89
|
+
ok: true;
|
|
90
|
+
args: Record<string, unknown>;
|
|
91
|
+
} | {
|
|
92
|
+
ok: false;
|
|
93
|
+
error: string;
|
|
94
|
+
};
|
|
67
95
|
/**
|
|
68
96
|
* Mount the runtime-served MCP surface at `/app/mcp` (ADR 0067). Returns a single `*`-method route
|
|
69
97
|
* (mounted unconditionally, like `/app/agent`); the handler bridges the host request/response seam
|
|
@@ -286,7 +286,7 @@ function toHttpRequest(op, args, forwardHeaders) {
|
|
|
286
286
|
* `collectOperations`). As defence in depth, if that metadata is somehow still a bare `$ref` (it
|
|
287
287
|
* should never be after resolution), re-resolve it via {@link resolveSchema} against `doc` so the
|
|
288
288
|
* classification below never keys off an opaque `#/components/...` pointer. */
|
|
289
|
-
function effectiveRequestBodySchema(op, doc) {
|
|
289
|
+
export function effectiveRequestBodySchema(op, doc) {
|
|
290
290
|
const schema = op.requestBodySchemaResolved ?? op.requestBodySchema;
|
|
291
291
|
if (schema?.$ref)
|
|
292
292
|
return doc ? resolveSchema(doc, schema) : undefined;
|
|
@@ -296,7 +296,7 @@ function effectiveRequestBodySchema(op, doc) {
|
|
|
296
296
|
* expects as a JSON object/array rather than a bare scalar. Classified from the RESOLVED schema so a
|
|
297
297
|
* `$ref`-bodied op (e.g. `previewDeliveryGraph`, whose object `type` is only visible after P0's
|
|
298
298
|
* resolution) is recognized, not merely an inline-`type` object body. */
|
|
299
|
-
function structuredBodyKind(schema) {
|
|
299
|
+
export function structuredBodyKind(schema) {
|
|
300
300
|
if (!schema)
|
|
301
301
|
return undefined;
|
|
302
302
|
if (isObjectSchema(schema))
|
|
@@ -314,7 +314,7 @@ function structuredBodyKind(schema) {
|
|
|
314
314
|
* passes through untouched (still serialized by the transport). A string that does not parse to the
|
|
315
315
|
* declared shape is a CLEAR tool error naming the expected shape — never a silently double-encoded
|
|
316
316
|
* (and 4xx-rejected) request. */
|
|
317
|
-
function normalizeBodyArg(op, args, doc) {
|
|
317
|
+
export function normalizeBodyArg(op, args, doc) {
|
|
318
318
|
const body = args.body;
|
|
319
319
|
const kind = structuredBodyKind(effectiveRequestBodySchema(op, doc));
|
|
320
320
|
if (body === undefined || kind === undefined || typeof body !== "string") {
|