@m6d/cortex-server 2.1.0 → 2.3.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/README.md +23 -9
- package/contracts/README.md +22 -8
- package/contracts/src/client-tools/index.ts +56 -0
- package/contracts/src/graph/index.ts +30 -0
- package/contracts/{runtime.ts → src/runtime/index.ts} +7 -12
- package/contracts/{wire.ts → src/wire/index.ts} +25 -13
- package/dist/contracts/{graph.d.ts → src/graph/index.d.ts} +8 -8
- package/dist/contracts/{runtime.d.ts → src/runtime/index.d.ts} +9 -43
- package/dist/contracts/{wire.d.ts → src/wire/index.d.ts} +23 -13
- package/dist/src/lib/adapters/database/index.d.ts +0 -7
- package/dist/src/lib/adapters/database/message-content.d.ts +1 -2
- package/dist/src/lib/adapters/database/mssql/index.d.ts +0 -1
- package/dist/src/lib/adapters/database/mssql/messages.d.ts +0 -1
- package/dist/src/lib/adapters/database/postgres/index.d.ts +0 -1
- package/dist/src/lib/adapters/database/postgres/messages.d.ts +0 -1
- package/dist/src/lib/ai/cc-runtime.d.ts +2 -3
- package/dist/src/lib/ai/client-tools.d.ts +84 -0
- package/dist/src/lib/ai/tools/query-graph.tool.d.ts +1 -1
- package/dist/src/lib/ai/turn-tools.d.ts +8 -6
- package/dist/src/lib/cc/client.d.ts +4 -11
- package/dist/src/lib/cc/config-cache.d.ts +0 -1
- package/dist/src/lib/cc/registry.d.ts +6 -6
- package/dist/src/lib/cc/types.d.ts +1 -1
- package/dist/src/lib/config.d.ts +9 -4
- package/dist/src/lib/graph/index.d.ts +1 -1
- package/dist/src/lib/graph/resolver.d.ts +1 -1
- package/dist/src/lib/index.d.ts +2 -1
- package/dist/src/lib/types.d.ts +2 -2
- package/dist/src/lib/ws/connections.d.ts +1 -1
- package/package.json +2 -2
- package/src/lib/adapters/database/index.ts +0 -12
- package/src/lib/adapters/database/mssql/messages.ts +1 -28
- package/src/lib/adapters/database/postgres/messages.ts +1 -22
- package/src/lib/ai/cc-runtime.ts +7 -7
- package/src/lib/ai/client-tools.ts +288 -0
- package/src/lib/ai/index.ts +60 -47
- package/src/lib/ai/tools/search-tools.tool.ts +2 -2
- package/src/lib/ai/turn-tools.ts +7 -8
- package/src/lib/cc/client.ts +1 -1
- package/src/lib/cc/format.ts +2 -6
- package/src/lib/cc/registry.ts +7 -7
- package/src/lib/cc/types.ts +1 -1
- package/src/lib/config.ts +8 -3
- package/src/lib/index.ts +4 -0
- package/src/lib/routes/chat.ts +5 -5
- package/tsconfig.json +1 -1
- package/contracts/graph.ts +0 -36
- package/contracts/interactive.ts +0 -53
- package/dist/contracts/interactive.d.ts +0 -39
- package/dist/src/lib/ai/interactive.d.ts +0 -62
- package/src/lib/ai/interactive.ts +0 -364
- /package/contracts/{graph → src/graph/clients}/embed.ts +0 -0
- /package/contracts/{graph → src/graph/clients}/neo4j.ts +0 -0
- /package/contracts/{graph → src/graph}/helpers.ts +0 -0
- /package/contracts/{graph → src/graph}/schema.ts +0 -0
- /package/contracts/{graph → src/graph}/types.ts +0 -0
- /package/contracts/{rich-text.ts → src/rich-text/index.ts} +0 -0
- /package/dist/contracts/{graph → src/graph/clients}/embed.d.ts +0 -0
- /package/dist/contracts/{graph → src/graph/clients}/neo4j.d.ts +0 -0
- /package/dist/contracts/{graph → src/graph}/helpers.d.ts +0 -0
- /package/dist/contracts/{graph → src/graph}/schema.d.ts +0 -0
- /package/dist/contracts/{graph → src/graph}/types.d.ts +0 -0
- /package/dist/contracts/{rich-text.d.ts → src/rich-text/index.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -64,15 +64,29 @@ Only `database`, `model`, and `agents` are required for a minimal setup. `storag
|
|
|
64
64
|
|
|
65
65
|
Each key in `agents` becomes a route prefix (e.g. `assistant` → `/agents/assistant/...`). Agents can define per-agent `systemPrompt`, `tools`, `backendFetch`, `loadSessionData`, `resolveRequestContext`, and lifecycle hooks (`onToolCall`, `onStreamFinish`).
|
|
66
66
|
|
|
67
|
-
##
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
67
|
+
## Client tools
|
|
68
|
+
|
|
69
|
+
A tool in an agent's `tools` with an `execute` function runs on the server. One
|
|
70
|
+
without is a static client tool: it is declared to the model, the call streams
|
|
71
|
+
to the widget, and the host app answers it via `hooks.onToolCall` (or a
|
|
72
|
+
`toolComponents` entry calling `setOutput`).
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
const getBrowserTimezone = toolDefinition({
|
|
76
|
+
name: "getBrowserTimezone",
|
|
77
|
+
description: "Read the user's IANA time zone from their browser.",
|
|
78
|
+
inputSchema: z.object({}),
|
|
79
|
+
}).client();
|
|
80
|
+
// agents.sample.tools = [getBrowserTimezone]
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Control-Center tools published with type "embedded" are the dynamic client
|
|
84
|
+
tools: declared the same way, but the widget first calls
|
|
85
|
+
`POST /chat/:chatId/tools/:toolCallId/initiate`, which runs the tool's endpoint
|
|
86
|
+
server-to-server and hands the widget its embed payload (never the model).
|
|
87
|
+
The result the embedded page reports back is relayed to the agent as-is —
|
|
88
|
+
verifying it is the integrating backend's job. See
|
|
89
|
+
`apps/cortex-cc/docs/client-tools.md` for authoring them.
|
|
76
90
|
|
|
77
91
|
## Requirements
|
|
78
92
|
|
package/contracts/README.md
CHANGED
|
@@ -4,18 +4,32 @@ The shapes both sides of a cortex boundary must agree on. Private on purpose —
|
|
|
4
4
|
it never publishes; each publishable package carries its own copy:
|
|
5
5
|
|
|
6
6
|
- `@m6d/cortex-server` and `@m6d/cortex-cli` publish raw source, so their
|
|
7
|
-
`prepack` vendors a copy of
|
|
7
|
+
`prepack` vendors a copy of `src/` into the tarball (`contracts/src/` and
|
|
8
8
|
`src/contracts/` respectively), resolved there by their shipped tsconfig paths.
|
|
9
9
|
- `@m6d/cortex-angular` and `@m6d/cortex-react` compile the parts they import
|
|
10
|
-
into their build artifacts
|
|
10
|
+
into their build artifacts (angular's `vendor` copies the seam directories
|
|
11
|
+
into `src/internal/`).
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
## Layout
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
Every seam is a directory: `src/<seam>/index.ts`, split into focused files
|
|
16
|
+
under the directory where that helps (see `graph/`). The `exports` map is a
|
|
17
|
+
single wildcard (`"./*": "./src/*/index.ts"`), so adding a seam is adding a
|
|
18
|
+
directory — no manifest edit, no consumer tsconfig edit for wildcard-mapped
|
|
19
|
+
consumers (server, cli, sample-server, cc).
|
|
20
|
+
|
|
21
|
+
| import | boundary | consumers |
|
|
22
|
+
| -------------------------------- | ---------------------------------------------------- | ------------------------------------------------------- |
|
|
23
|
+
| `@cortex/contracts/wire` | chat client ↔ server (HTTP/WebSocket types) | server, client SDKs (`internal/client`, angular, react) |
|
|
24
|
+
| `@cortex/contracts/client-tools` | embedded page ↔ chat widget handshake | server, client SDKs |
|
|
25
|
+
| `@cortex/contracts/runtime` | cortex-cc console ↔ server runtime API (zod schemas) | server, cortex-cc |
|
|
26
|
+
| `@cortex/contracts/rich-text` | prompt/description grammar (mentions, variables) | server, cortex-cc |
|
|
27
|
+
| `@cortex/contracts/graph` | graph authoring (cli) ↔ server (vocabulary, helpers) | server, cortex-cli |
|
|
28
|
+
|
|
29
|
+
`src/graph/clients/` is the one deliberate exception to "contracts only":
|
|
30
|
+
`neo4j.ts` and `embed.ts` are runtime I/O clients shared by the CLI and the
|
|
31
|
+
server. They live here so there is exactly one copy, vendored the same way as
|
|
32
|
+
everything else; they are re-exported through `@cortex/contracts/graph`.
|
|
19
33
|
|
|
20
34
|
Everything is consumed as TypeScript source — no build, no dist. Nothing here
|
|
21
35
|
has a runtime dependency beyond zod (for `/runtime`), and nothing here may grow
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The embed ↔ widget handshake for client tools.
|
|
3
|
+
*
|
|
4
|
+
* A page embedded by the chat widget (a hosted checkout, signing page, …)
|
|
5
|
+
* reports its outcome with:
|
|
6
|
+
*
|
|
7
|
+
* window.parent.postMessage(
|
|
8
|
+
* { type: "cortex:client-tool", status: "completed", reference: "session_123" },
|
|
9
|
+
* "*",
|
|
10
|
+
* );
|
|
11
|
+
*
|
|
12
|
+
* The widget accepts the message only when the event's origin matches the
|
|
13
|
+
* tool's configured `embedOrigin`. The payload is the page's claim, relayed to
|
|
14
|
+
* the agent as-is: cortex does not verify it, and anything that must actually
|
|
15
|
+
* be true lives in the integrating backend's own records.
|
|
16
|
+
*
|
|
17
|
+
* Like the wire seam, this file is compiled into the client SDKs and must stay
|
|
18
|
+
* free of runtime dependencies. It is also the spec any future SDK (Flutter)
|
|
19
|
+
* reimplements against.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
export const CLIENT_TOOL_MESSAGE_TYPE = "cortex:client-tool";
|
|
23
|
+
|
|
24
|
+
export const CLIENT_TOOL_STATUSES = ["completed", "cancelled", "failed"] as const;
|
|
25
|
+
|
|
26
|
+
export type ClientToolStatus = (typeof CLIENT_TOOL_STATUSES)[number];
|
|
27
|
+
|
|
28
|
+
export type ClientToolHandshake = {
|
|
29
|
+
type: typeof CLIENT_TOOL_MESSAGE_TYPE;
|
|
30
|
+
status: ClientToolStatus;
|
|
31
|
+
/** Opaque id for the integrating backend's own bookkeeping (session id, envelope id, …). */
|
|
32
|
+
reference?: string;
|
|
33
|
+
/** Optional payload passed through to the agent as part of the tool result. */
|
|
34
|
+
result?: unknown;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Parse a `message` event into a handshake, or null when the origin doesn't
|
|
39
|
+
* match the tool's `embedOrigin` or the payload isn't a well-formed handshake.
|
|
40
|
+
* Call from the widget's `message` listener with `event.data` / `event.origin`.
|
|
41
|
+
*/
|
|
42
|
+
export function parseClientToolHandshake(data: unknown, origin: string, embedOrigin: string) {
|
|
43
|
+
if (origin !== embedOrigin) return null;
|
|
44
|
+
if (typeof data !== "object" || data === null) return null;
|
|
45
|
+
const message = data as Record<string, unknown>;
|
|
46
|
+
if (message["type"] !== CLIENT_TOOL_MESSAGE_TYPE) return null;
|
|
47
|
+
const status = CLIENT_TOOL_STATUSES.find((known) => known === message["status"]);
|
|
48
|
+
if (!status) return null;
|
|
49
|
+
const reference = message["reference"];
|
|
50
|
+
return {
|
|
51
|
+
type: CLIENT_TOOL_MESSAGE_TYPE,
|
|
52
|
+
status,
|
|
53
|
+
...(typeof reference === "string" ? { reference } : {}),
|
|
54
|
+
...(message["result"] !== undefined ? { result: message["result"] } : {}),
|
|
55
|
+
} satisfies ClientToolHandshake;
|
|
56
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The graph contract — the knowledge-graph vocabulary, authoring types and
|
|
3
|
+
* clients that `@m6d/cortex-cli` writes with and `@m6d/cortex-server` reads
|
|
4
|
+
* with. `@m6d/cortex-server` re-exports all of it, so a project authoring
|
|
5
|
+
* domains still has exactly one import path.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export type { GraphSchema } from "./schema";
|
|
9
|
+
export { GRAPH_SCHEMA, GRAPH_SCHEMA_VERSION } from "./schema";
|
|
10
|
+
|
|
11
|
+
export type {
|
|
12
|
+
EndpointScalarType,
|
|
13
|
+
EndpointProperty,
|
|
14
|
+
ResponseKind,
|
|
15
|
+
AutoGenerated,
|
|
16
|
+
ConceptDef,
|
|
17
|
+
EndpointDef,
|
|
18
|
+
EndpointInput,
|
|
19
|
+
ServiceDef,
|
|
20
|
+
RuleDef,
|
|
21
|
+
DomainDef,
|
|
22
|
+
} from "./types";
|
|
23
|
+
|
|
24
|
+
export { defineConcept, defineRule, defineService, defineDomain, defineEndpoint } from "./helpers";
|
|
25
|
+
|
|
26
|
+
export type { Neo4jConfig, Neo4jClient } from "./clients/neo4j";
|
|
27
|
+
export { createNeo4jClient } from "./clients/neo4j";
|
|
28
|
+
|
|
29
|
+
export type { EmbedFn, EmbeddingProviderConfig } from "./clients/embed";
|
|
30
|
+
export { createEmbedder } from "./clients/embed";
|
|
@@ -90,16 +90,15 @@ export const knowledgeChunkSchema = z.object({
|
|
|
90
90
|
});
|
|
91
91
|
|
|
92
92
|
/**
|
|
93
|
-
* Runtime contract §5.4: present on signatures of `
|
|
93
|
+
* Runtime contract §5.4: present on signatures of `embedded` tools — flows
|
|
94
94
|
* the end user completes in an embedded surface inside the chat widget. The
|
|
95
95
|
* tool's endpoint fields act as the *initiate* call (returns the embed URL);
|
|
96
|
-
*
|
|
96
|
+
* the result the page reports back is relayed as-is — verifying it is the
|
|
97
|
+
* integrating backend's job.
|
|
97
98
|
*/
|
|
98
|
-
export const
|
|
99
|
+
export const toolEmbedSchema = z.object({
|
|
99
100
|
surface: z.enum(["inline", "modal"]),
|
|
100
101
|
embedOrigin: z.url(),
|
|
101
|
-
hasVerify: z.boolean(),
|
|
102
|
-
resultDelivery: z.enum(["agent", "endpoint", "both"]),
|
|
103
102
|
});
|
|
104
103
|
|
|
105
104
|
export const toolSignatureSchema = z.object({
|
|
@@ -111,8 +110,8 @@ export const toolSignatureSchema = z.object({
|
|
|
111
110
|
signature: z.string(),
|
|
112
111
|
score: z.number().nullable(),
|
|
113
112
|
pinned: z.boolean(),
|
|
114
|
-
|
|
115
|
-
/**
|
|
113
|
+
embed: toolEmbedSchema.optional(),
|
|
114
|
+
/** Client tools only: the published input JSON Schema, verbatim.
|
|
116
115
|
* Client-executed declarations need a real schema — the rendered
|
|
117
116
|
* `signature` text alone is not enough for function calling. */
|
|
118
117
|
inputSchema: z.record(z.string(), z.unknown()).optional(),
|
|
@@ -133,7 +132,6 @@ export const runtimeAgentConfigSchema = z.object({
|
|
|
133
132
|
agentId: agentSlugSchema,
|
|
134
133
|
systemPrompt: z.string(),
|
|
135
134
|
promptVariables: z.array(z.enum(PROMPT_VARIABLES)),
|
|
136
|
-
catalogBlurb: z.string(),
|
|
137
135
|
defaultLocale: localeSchema,
|
|
138
136
|
metaTools: z.object({
|
|
139
137
|
searchKnowledge: z.boolean(),
|
|
@@ -212,9 +210,6 @@ export const searchKnowledgeResponseSchema = z.object({
|
|
|
212
210
|
|
|
213
211
|
export const executeRequestSchema = z.object({
|
|
214
212
|
input: z.record(z.string(), z.unknown()).default({}),
|
|
215
|
-
// Interactive tools only: absent | "initiate" targets the tool's endpoint
|
|
216
|
-
// fields, "verify" targets its verify endpoint config.
|
|
217
|
-
phase: z.enum(["initiate", "verify"]).optional(),
|
|
218
213
|
context: z
|
|
219
214
|
.object({
|
|
220
215
|
threadId: z.string().max(128).optional(),
|
|
@@ -257,7 +252,7 @@ export const runtimeErrorSchema = z.object({
|
|
|
257
252
|
}),
|
|
258
253
|
});
|
|
259
254
|
|
|
260
|
-
export type
|
|
255
|
+
export type ToolEmbed = z.infer<typeof toolEmbedSchema>;
|
|
261
256
|
export type RuntimeAgentConfig = z.infer<typeof runtimeAgentConfigSchema>;
|
|
262
257
|
export type ResolveRequest = z.input<typeof resolveRequestSchema>;
|
|
263
258
|
export type ResolveResponse = z.infer<typeof resolveResponseSchema>;
|
|
@@ -71,16 +71,14 @@ export type TokenUsage = {
|
|
|
71
71
|
};
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
|
-
* How to launch one
|
|
74
|
+
* How to launch one client tool: stamped by the server, per tool name, on
|
|
75
75
|
* the metadata of an assistant message that may carry its pending call. Kept in
|
|
76
76
|
* the message so the binding survives server restarts while a run is parked.
|
|
77
77
|
*/
|
|
78
|
-
export type
|
|
78
|
+
export type ClientToolBinding = {
|
|
79
79
|
toolId: string;
|
|
80
80
|
surface: "inline" | "modal";
|
|
81
81
|
embedOrigin: string;
|
|
82
|
-
hasVerify: boolean;
|
|
83
|
-
resultDelivery: "agent" | "endpoint" | "both";
|
|
84
82
|
};
|
|
85
83
|
|
|
86
84
|
export type MessageMetadata = {
|
|
@@ -89,10 +87,7 @@ export type MessageMetadata = {
|
|
|
89
87
|
isAborted?: boolean;
|
|
90
88
|
tokenUsage?: TokenUsage;
|
|
91
89
|
attachments?: AttachmentSummary[];
|
|
92
|
-
|
|
93
|
-
/** Per tool call: the trusted reference its initiate call returned. A
|
|
94
|
-
* verified completion must match it — the browser's word is never enough. */
|
|
95
|
-
interactiveReferences?: Record<string, string>;
|
|
90
|
+
clientTools?: Record<string, ClientToolBinding>;
|
|
96
91
|
};
|
|
97
92
|
|
|
98
93
|
/**
|
|
@@ -111,15 +106,32 @@ export type CortexMessage<TPart = unknown> = {
|
|
|
111
106
|
};
|
|
112
107
|
|
|
113
108
|
/**
|
|
114
|
-
*
|
|
115
|
-
*
|
|
109
|
+
* Key under the AG-UI request's `forwardedProps` carrying the answers to
|
|
110
|
+
* parked client tool calls on a continuation request. The server owns the
|
|
111
|
+
* transcript (a continuation sends `messages: []`), so the answered assistant
|
|
112
|
+
* message itself never crosses the wire — the SDK's park-boundary snapshot
|
|
113
|
+
* does not preserve its id, and round-tripping it duplicated the stored
|
|
114
|
+
* message.
|
|
115
|
+
*/
|
|
116
|
+
export const CLIENT_TOOL_ANSWERS_KEY = "clientToolAnswers";
|
|
117
|
+
|
|
118
|
+
/** One answered client tool call, applied to the stored transcript server-side. */
|
|
119
|
+
export type ClientToolAnswer = {
|
|
120
|
+
toolCallId: string;
|
|
121
|
+
output: unknown;
|
|
122
|
+
state: "complete" | "error";
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Response of `POST /chat/:chatId/tools/:toolCallId/initiate`. `embed:
|
|
127
|
+
* false` means the pending call is not a CC client tool — the widget
|
|
116
128
|
* falls back to its default rendering for the call. The payload is for the
|
|
117
129
|
* widget only; it never reaches the LLM.
|
|
118
130
|
*/
|
|
119
|
-
export type
|
|
120
|
-
| {
|
|
131
|
+
export type ClientToolInitiateResult =
|
|
132
|
+
| { embed: false }
|
|
121
133
|
| {
|
|
122
|
-
|
|
134
|
+
embed: true;
|
|
123
135
|
embedUrl: string;
|
|
124
136
|
surface: "inline" | "modal";
|
|
125
137
|
embedOrigin: string;
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
* with. `@m6d/cortex-server` re-exports all of it, so a project authoring
|
|
5
5
|
* domains still has exactly one import path.
|
|
6
6
|
*/
|
|
7
|
-
export type { GraphSchema } from "./
|
|
8
|
-
export { GRAPH_SCHEMA, GRAPH_SCHEMA_VERSION } from "./
|
|
9
|
-
export type { EndpointScalarType, EndpointProperty, ResponseKind, AutoGenerated, ConceptDef, EndpointDef, EndpointInput, ServiceDef, RuleDef, DomainDef, } from "./
|
|
10
|
-
export { defineConcept, defineRule, defineService, defineDomain, defineEndpoint
|
|
11
|
-
export type { Neo4jConfig, Neo4jClient } from "./
|
|
12
|
-
export { createNeo4jClient } from "./
|
|
13
|
-
export type { EmbedFn, EmbeddingProviderConfig } from "./
|
|
14
|
-
export { createEmbedder } from "./
|
|
7
|
+
export type { GraphSchema } from "./schema";
|
|
8
|
+
export { GRAPH_SCHEMA, GRAPH_SCHEMA_VERSION } from "./schema";
|
|
9
|
+
export type { EndpointScalarType, EndpointProperty, ResponseKind, AutoGenerated, ConceptDef, EndpointDef, EndpointInput, ServiceDef, RuleDef, DomainDef, } from "./types";
|
|
10
|
+
export { defineConcept, defineRule, defineService, defineDomain, defineEndpoint } from "./helpers";
|
|
11
|
+
export type { Neo4jConfig, Neo4jClient } from "./clients/neo4j";
|
|
12
|
+
export { createNeo4jClient } from "./clients/neo4j";
|
|
13
|
+
export type { EmbedFn, EmbeddingProviderConfig } from "./clients/embed";
|
|
14
|
+
export { createEmbedder } from "./clients/embed";
|
|
@@ -61,23 +61,18 @@ export declare const knowledgeChunkSchema: z.ZodObject<{
|
|
|
61
61
|
}, z.core.$strip>;
|
|
62
62
|
}, z.core.$strip>;
|
|
63
63
|
/**
|
|
64
|
-
* Runtime contract §5.4: present on signatures of `
|
|
64
|
+
* Runtime contract §5.4: present on signatures of `embedded` tools — flows
|
|
65
65
|
* the end user completes in an embedded surface inside the chat widget. The
|
|
66
66
|
* tool's endpoint fields act as the *initiate* call (returns the embed URL);
|
|
67
|
-
*
|
|
67
|
+
* the result the page reports back is relayed as-is — verifying it is the
|
|
68
|
+
* integrating backend's job.
|
|
68
69
|
*/
|
|
69
|
-
export declare const
|
|
70
|
+
export declare const toolEmbedSchema: z.ZodObject<{
|
|
70
71
|
surface: z.ZodEnum<{
|
|
71
72
|
inline: "inline";
|
|
72
73
|
modal: "modal";
|
|
73
74
|
}>;
|
|
74
75
|
embedOrigin: z.ZodURL;
|
|
75
|
-
hasVerify: z.ZodBoolean;
|
|
76
|
-
resultDelivery: z.ZodEnum<{
|
|
77
|
-
agent: "agent";
|
|
78
|
-
endpoint: "endpoint";
|
|
79
|
-
both: "both";
|
|
80
|
-
}>;
|
|
81
76
|
}, z.core.$strip>;
|
|
82
77
|
export declare const toolSignatureSchema: z.ZodObject<{
|
|
83
78
|
toolId: z.ZodUUID;
|
|
@@ -88,18 +83,12 @@ export declare const toolSignatureSchema: z.ZodObject<{
|
|
|
88
83
|
signature: z.ZodString;
|
|
89
84
|
score: z.ZodNullable<z.ZodNumber>;
|
|
90
85
|
pinned: z.ZodBoolean;
|
|
91
|
-
|
|
86
|
+
embed: z.ZodOptional<z.ZodObject<{
|
|
92
87
|
surface: z.ZodEnum<{
|
|
93
88
|
inline: "inline";
|
|
94
89
|
modal: "modal";
|
|
95
90
|
}>;
|
|
96
91
|
embedOrigin: z.ZodURL;
|
|
97
|
-
hasVerify: z.ZodBoolean;
|
|
98
|
-
resultDelivery: z.ZodEnum<{
|
|
99
|
-
agent: "agent";
|
|
100
|
-
endpoint: "endpoint";
|
|
101
|
-
both: "both";
|
|
102
|
-
}>;
|
|
103
92
|
}, z.core.$strip>>;
|
|
104
93
|
inputSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
105
94
|
}, z.core.$strip>;
|
|
@@ -120,7 +109,6 @@ export declare const runtimeAgentConfigSchema: z.ZodObject<{
|
|
|
120
109
|
utcTime: "utcTime";
|
|
121
110
|
timezone: "timezone";
|
|
122
111
|
}>>;
|
|
123
|
-
catalogBlurb: z.ZodString;
|
|
124
112
|
defaultLocale: z.ZodEnum<{
|
|
125
113
|
ar: "ar";
|
|
126
114
|
en: "en";
|
|
@@ -185,18 +173,12 @@ export declare const resolveResponseSchema: z.ZodObject<{
|
|
|
185
173
|
signature: z.ZodString;
|
|
186
174
|
score: z.ZodNullable<z.ZodNumber>;
|
|
187
175
|
pinned: z.ZodBoolean;
|
|
188
|
-
|
|
176
|
+
embed: z.ZodOptional<z.ZodObject<{
|
|
189
177
|
surface: z.ZodEnum<{
|
|
190
178
|
inline: "inline";
|
|
191
179
|
modal: "modal";
|
|
192
180
|
}>;
|
|
193
181
|
embedOrigin: z.ZodURL;
|
|
194
|
-
hasVerify: z.ZodBoolean;
|
|
195
|
-
resultDelivery: z.ZodEnum<{
|
|
196
|
-
agent: "agent";
|
|
197
|
-
endpoint: "endpoint";
|
|
198
|
-
both: "both";
|
|
199
|
-
}>;
|
|
200
182
|
}, z.core.$strip>>;
|
|
201
183
|
inputSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
202
184
|
}, z.core.$strip>>;
|
|
@@ -238,18 +220,12 @@ export declare const searchToolsResponseSchema: z.ZodObject<{
|
|
|
238
220
|
signature: z.ZodString;
|
|
239
221
|
score: z.ZodNullable<z.ZodNumber>;
|
|
240
222
|
pinned: z.ZodBoolean;
|
|
241
|
-
|
|
223
|
+
embed: z.ZodOptional<z.ZodObject<{
|
|
242
224
|
surface: z.ZodEnum<{
|
|
243
225
|
inline: "inline";
|
|
244
226
|
modal: "modal";
|
|
245
227
|
}>;
|
|
246
228
|
embedOrigin: z.ZodURL;
|
|
247
|
-
hasVerify: z.ZodBoolean;
|
|
248
|
-
resultDelivery: z.ZodEnum<{
|
|
249
|
-
agent: "agent";
|
|
250
|
-
endpoint: "endpoint";
|
|
251
|
-
both: "both";
|
|
252
|
-
}>;
|
|
253
229
|
}, z.core.$strip>>;
|
|
254
230
|
inputSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
255
231
|
}, z.core.$strip>>;
|
|
@@ -276,18 +252,12 @@ export declare const searchServicesResponseSchema: z.ZodObject<{
|
|
|
276
252
|
signature: z.ZodString;
|
|
277
253
|
score: z.ZodNullable<z.ZodNumber>;
|
|
278
254
|
pinned: z.ZodBoolean;
|
|
279
|
-
|
|
255
|
+
embed: z.ZodOptional<z.ZodObject<{
|
|
280
256
|
surface: z.ZodEnum<{
|
|
281
257
|
inline: "inline";
|
|
282
258
|
modal: "modal";
|
|
283
259
|
}>;
|
|
284
260
|
embedOrigin: z.ZodURL;
|
|
285
|
-
hasVerify: z.ZodBoolean;
|
|
286
|
-
resultDelivery: z.ZodEnum<{
|
|
287
|
-
agent: "agent";
|
|
288
|
-
endpoint: "endpoint";
|
|
289
|
-
both: "both";
|
|
290
|
-
}>;
|
|
291
261
|
}, z.core.$strip>>;
|
|
292
262
|
inputSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
293
263
|
}, z.core.$strip>>;
|
|
@@ -314,10 +284,6 @@ export declare const searchKnowledgeResponseSchema: z.ZodObject<{
|
|
|
314
284
|
}, z.core.$strip>;
|
|
315
285
|
export declare const executeRequestSchema: z.ZodObject<{
|
|
316
286
|
input: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
317
|
-
phase: z.ZodOptional<z.ZodEnum<{
|
|
318
|
-
verify: "verify";
|
|
319
|
-
initiate: "initiate";
|
|
320
|
-
}>>;
|
|
321
287
|
context: z.ZodOptional<z.ZodObject<{
|
|
322
288
|
threadId: z.ZodOptional<z.ZodString>;
|
|
323
289
|
userId: z.ZodOptional<z.ZodString>;
|
|
@@ -381,7 +347,7 @@ export declare const runtimeErrorSchema: z.ZodObject<{
|
|
|
381
347
|
upstreamStatus: z.ZodOptional<z.ZodNumber>;
|
|
382
348
|
}, z.core.$strip>;
|
|
383
349
|
}, z.core.$strip>;
|
|
384
|
-
export type
|
|
350
|
+
export type ToolEmbed = z.infer<typeof toolEmbedSchema>;
|
|
385
351
|
export type RuntimeAgentConfig = z.infer<typeof runtimeAgentConfigSchema>;
|
|
386
352
|
export type ResolveRequest = z.input<typeof resolveRequestSchema>;
|
|
387
353
|
export type ResolveResponse = z.infer<typeof resolveResponseSchema>;
|
|
@@ -51,16 +51,14 @@ export type TokenUsage = {
|
|
|
51
51
|
total: number;
|
|
52
52
|
};
|
|
53
53
|
/**
|
|
54
|
-
* How to launch one
|
|
54
|
+
* How to launch one client tool: stamped by the server, per tool name, on
|
|
55
55
|
* the metadata of an assistant message that may carry its pending call. Kept in
|
|
56
56
|
* the message so the binding survives server restarts while a run is parked.
|
|
57
57
|
*/
|
|
58
|
-
export type
|
|
58
|
+
export type ClientToolBinding = {
|
|
59
59
|
toolId: string;
|
|
60
60
|
surface: "inline" | "modal";
|
|
61
61
|
embedOrigin: string;
|
|
62
|
-
hasVerify: boolean;
|
|
63
|
-
resultDelivery: "agent" | "endpoint" | "both";
|
|
64
62
|
};
|
|
65
63
|
export type MessageMetadata = {
|
|
66
64
|
modelId?: string;
|
|
@@ -68,10 +66,7 @@ export type MessageMetadata = {
|
|
|
68
66
|
isAborted?: boolean;
|
|
69
67
|
tokenUsage?: TokenUsage;
|
|
70
68
|
attachments?: AttachmentSummary[];
|
|
71
|
-
|
|
72
|
-
/** Per tool call: the trusted reference its initiate call returned. A
|
|
73
|
-
* verified completion must match it — the browser's word is never enough. */
|
|
74
|
-
interactiveReferences?: Record<string, string>;
|
|
69
|
+
clientTools?: Record<string, ClientToolBinding>;
|
|
75
70
|
};
|
|
76
71
|
/**
|
|
77
72
|
* A stored message as it is persisted and served. TanStack AI's `UIMessage`
|
|
@@ -88,15 +83,30 @@ export type CortexMessage<TPart = unknown> = {
|
|
|
88
83
|
metadata?: MessageMetadata;
|
|
89
84
|
};
|
|
90
85
|
/**
|
|
91
|
-
*
|
|
92
|
-
*
|
|
86
|
+
* Key under the AG-UI request's `forwardedProps` carrying the answers to
|
|
87
|
+
* parked client tool calls on a continuation request. The server owns the
|
|
88
|
+
* transcript (a continuation sends `messages: []`), so the answered assistant
|
|
89
|
+
* message itself never crosses the wire — the SDK's park-boundary snapshot
|
|
90
|
+
* does not preserve its id, and round-tripping it duplicated the stored
|
|
91
|
+
* message.
|
|
92
|
+
*/
|
|
93
|
+
export declare const CLIENT_TOOL_ANSWERS_KEY = "clientToolAnswers";
|
|
94
|
+
/** One answered client tool call, applied to the stored transcript server-side. */
|
|
95
|
+
export type ClientToolAnswer = {
|
|
96
|
+
toolCallId: string;
|
|
97
|
+
output: unknown;
|
|
98
|
+
state: "complete" | "error";
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Response of `POST /chat/:chatId/tools/:toolCallId/initiate`. `embed:
|
|
102
|
+
* false` means the pending call is not a CC client tool — the widget
|
|
93
103
|
* falls back to its default rendering for the call. The payload is for the
|
|
94
104
|
* widget only; it never reaches the LLM.
|
|
95
105
|
*/
|
|
96
|
-
export type
|
|
97
|
-
|
|
106
|
+
export type ClientToolInitiateResult = {
|
|
107
|
+
embed: false;
|
|
98
108
|
} | {
|
|
99
|
-
|
|
109
|
+
embed: true;
|
|
100
110
|
embedUrl: string;
|
|
101
111
|
surface: "inline" | "modal";
|
|
102
112
|
embedOrigin: string;
|
|
@@ -34,13 +34,6 @@ export type DatabaseAdapter = {
|
|
|
34
34
|
upsert(threadId: string, messages: ChatMessage[], options?: {
|
|
35
35
|
replaceAttachments?: boolean;
|
|
36
36
|
}): Promise<void>;
|
|
37
|
-
/**
|
|
38
|
-
* Atomically merges one anchored interactive reference into the
|
|
39
|
-
* message's metadata as a single-statement JSON merge — safe under
|
|
40
|
-
* concurrent writers across replicas, unlike a read-modify-write of
|
|
41
|
-
* the whole message.
|
|
42
|
-
*/
|
|
43
|
-
mergeInteractiveReference(threadId: string, messageId: string, toolCallId: string, reference: string): Promise<void>;
|
|
44
37
|
};
|
|
45
38
|
llmRequests: {
|
|
46
39
|
insert(requests: {
|
|
@@ -16,8 +16,7 @@ export declare function withOwnedAttachments(messages: ChatMessage[], replaceAtt
|
|
|
16
16
|
providerMetadata?: unknown;
|
|
17
17
|
isAborted?: boolean;
|
|
18
18
|
tokenUsage?: import("../../types").TokenUsage;
|
|
19
|
-
|
|
20
|
-
interactiveReferences?: Record<string, string>;
|
|
19
|
+
clientTools?: Record<string, import("../..").ClientToolBinding>;
|
|
21
20
|
};
|
|
22
21
|
id: string;
|
|
23
22
|
role: "system" | "user" | "assistant";
|
|
@@ -76,7 +76,6 @@ export declare function createMssqlAdapter(connectionString: string, storage?: S
|
|
|
76
76
|
upsert(threadId: string, messagesToUpsert: import("../../../types").ChatMessage[], options?: {
|
|
77
77
|
replaceAttachments?: boolean;
|
|
78
78
|
}): Promise<void>;
|
|
79
|
-
mergeInteractiveReference(threadId: string, messageId: string, toolCallId: string, reference: string): Promise<void>;
|
|
80
79
|
};
|
|
81
80
|
llmRequests: {
|
|
82
81
|
insert(requests: {
|
|
@@ -34,5 +34,4 @@ export declare function createMessagesRepository(db: MssqlDb): {
|
|
|
34
34
|
upsert(threadId: string, messagesToUpsert: ChatMessage[], options?: {
|
|
35
35
|
replaceAttachments?: boolean;
|
|
36
36
|
}): Promise<void>;
|
|
37
|
-
mergeInteractiveReference(threadId: string, messageId: string, toolCallId: string, reference: string): Promise<void>;
|
|
38
37
|
};
|
|
@@ -76,7 +76,6 @@ export declare function createPostgresAdapter(connectionString: string, storage?
|
|
|
76
76
|
upsert(threadId: string, messagesToUpsert: import("../../../types").ChatMessage[], options?: {
|
|
77
77
|
replaceAttachments?: boolean;
|
|
78
78
|
}): Promise<void>;
|
|
79
|
-
mergeInteractiveReference(threadId: string, messageId: string, toolCallId: string, reference: string): Promise<void>;
|
|
80
79
|
};
|
|
81
80
|
llmRequests: {
|
|
82
81
|
insert(requests: {
|
|
@@ -34,5 +34,4 @@ export declare function createMessagesRepository(db: PostgresDb): {
|
|
|
34
34
|
upsert(threadId: string, messagesToUpsert: ChatMessage[], options?: {
|
|
35
35
|
replaceAttachments?: boolean;
|
|
36
36
|
}): Promise<void>;
|
|
37
|
-
mergeInteractiveReference(threadId: string, messageId: string, toolCallId: string, reference: string): Promise<void>;
|
|
38
37
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ResolvedCortexAgentConfig } from "../config";
|
|
2
2
|
import type { Thread } from "../types";
|
|
3
3
|
import type { ControlCenterClient } from "../cc/client";
|
|
4
|
-
import type {
|
|
4
|
+
import type { CcClientTool, CcToolRegistry } from "../cc/registry";
|
|
5
5
|
import type { ResolveResponse, RuntimeAgentConfig } from "../cc/types";
|
|
6
6
|
type CcRuntimeOptions = {
|
|
7
7
|
ccClient: ControlCenterClient | null;
|
|
@@ -32,7 +32,6 @@ export declare function createCcRuntime(options: CcRuntimeOptions): {
|
|
|
32
32
|
agentId: string;
|
|
33
33
|
systemPrompt: string;
|
|
34
34
|
promptVariables: ("userName" | "channel" | "locale" | "utcTime" | "timezone")[];
|
|
35
|
-
catalogBlurb: string;
|
|
36
35
|
defaultLocale: "ar" | "en";
|
|
37
36
|
metaTools: {
|
|
38
37
|
searchKnowledge: boolean;
|
|
@@ -48,7 +47,7 @@ export declare function createCcRuntime(options: CcRuntimeOptions): {
|
|
|
48
47
|
publishedAt: string;
|
|
49
48
|
};
|
|
50
49
|
registry: CcToolRegistry;
|
|
51
|
-
|
|
50
|
+
clientTools: Map<string, CcClientTool>;
|
|
52
51
|
threadId: string;
|
|
53
52
|
turnKey: string;
|
|
54
53
|
userId: string;
|