@tulip-systems/ai 0.11.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.
Files changed (129) hide show
  1. package/LICENSE +662 -0
  2. package/dist/agents/lib/definitions.server.d.mts +11 -0
  3. package/dist/agents/lib/definitions.server.mjs +14 -0
  4. package/dist/agents/lib/delegation.server.d.mts +15 -0
  5. package/dist/agents/lib/delegation.server.mjs +28 -0
  6. package/dist/agents/lib/instructions.server.d.mts +14 -0
  7. package/dist/agents/lib/instructions.server.mjs +26 -0
  8. package/dist/agents/lib/types.d.mts +26 -0
  9. package/dist/agents/server.d.mts +5 -0
  10. package/dist/agents/server.mjs +5 -0
  11. package/dist/chat/client.d.mts +10 -0
  12. package/dist/chat/client.mjs +12 -0
  13. package/dist/chat/components/agent-activity.client.d.mts +14 -0
  14. package/dist/chat/components/agent-activity.client.mjs +26 -0
  15. package/dist/chat/components/assistant-panel.client.d.mts +40 -0
  16. package/dist/chat/components/assistant-panel.client.mjs +53 -0
  17. package/dist/chat/components/chat-composer.client.d.mts +160 -0
  18. package/dist/chat/components/chat-composer.client.mjs +266 -0
  19. package/dist/chat/components/chat-message.client.d.mts +92 -0
  20. package/dist/chat/components/chat-message.client.mjs +121 -0
  21. package/dist/chat/components/chat-thread.client.d.mts +130 -0
  22. package/dist/chat/components/chat-thread.client.mjs +164 -0
  23. package/dist/chat/components/message-part.client.d.mts +23 -0
  24. package/dist/chat/components/message-part.client.mjs +38 -0
  25. package/dist/chat/components/starter-prompts.client.d.mts +25 -0
  26. package/dist/chat/components/starter-prompts.client.mjs +31 -0
  27. package/dist/chat/components/tool-call-card.client.d.mts +29 -0
  28. package/dist/chat/components/tool-call-card.client.mjs +60 -0
  29. package/dist/chat/lib/classes.mjs +7 -0
  30. package/dist/chat/lib/parts.d.mts +10 -0
  31. package/dist/chat/lib/parts.mjs +25 -0
  32. package/dist/chat/lib/stream.server.d.mts +24 -0
  33. package/dist/chat/lib/stream.server.mjs +34 -0
  34. package/dist/chat/lib/types.d.mts +21 -0
  35. package/dist/chat/server.d.mts +3 -0
  36. package/dist/chat/server.mjs +3 -0
  37. package/dist/chat.d.mts +3 -0
  38. package/dist/chat.mjs +3 -0
  39. package/dist/index.d.mts +1 -0
  40. package/dist/index.mjs +1 -0
  41. package/dist/mcp/lib/content.d.mts +66 -0
  42. package/dist/mcp/lib/content.d.mts.map +1 -0
  43. package/dist/mcp/lib/content.mjs +115 -0
  44. package/dist/mcp/lib/content.mjs.map +1 -0
  45. package/dist/mcp/lib/tool-result.server.d.mts +12 -0
  46. package/dist/mcp/lib/tool-result.server.d.mts.map +1 -0
  47. package/dist/mcp/lib/tool-result.server.mjs +10 -0
  48. package/dist/mcp/lib/tool-result.server.mjs.map +1 -0
  49. package/dist/mcp/lib/types.d.mts +27 -0
  50. package/dist/mcp/server.d.mts +3 -0
  51. package/dist/mcp/server.mjs +3 -0
  52. package/dist/mcp/types.d.mts +27 -0
  53. package/dist/mcp/types.d.mts.map +1 -0
  54. package/dist/server/mcp-content.d.mts +44 -0
  55. package/dist/server/mcp-content.d.mts.map +1 -0
  56. package/dist/server/mcp-content.mjs +71 -0
  57. package/dist/server/mcp-content.mjs.map +1 -0
  58. package/dist/server/tools.d.mts +61 -0
  59. package/dist/server/tools.d.mts.map +1 -0
  60. package/dist/server/tools.mjs +47 -0
  61. package/dist/server/tools.mjs.map +1 -0
  62. package/dist/server.d.mts +3 -0
  63. package/dist/server.mjs +4 -0
  64. package/dist/tools/client.d.mts +3 -0
  65. package/dist/tools/client.mjs +5 -0
  66. package/dist/tools/lib/ai-sdk.server.d.mts +12 -0
  67. package/dist/tools/lib/ai-sdk.server.d.mts.map +1 -0
  68. package/dist/tools/lib/ai-sdk.server.mjs +38 -0
  69. package/dist/tools/lib/ai-sdk.server.mjs.map +1 -0
  70. package/dist/tools/lib/define-tool.server.d.mts +9 -0
  71. package/dist/tools/lib/define-tool.server.d.mts.map +1 -0
  72. package/dist/tools/lib/define-tool.server.mjs +13 -0
  73. package/dist/tools/lib/define-tool.server.mjs.map +1 -0
  74. package/dist/tools/lib/definitions.client.d.mts +20 -0
  75. package/dist/tools/lib/definitions.client.mjs +21 -0
  76. package/dist/tools/lib/definitions.d.mts +16 -0
  77. package/dist/tools/lib/definitions.d.mts.map +1 -0
  78. package/dist/tools/lib/definitions.mjs +20 -0
  79. package/dist/tools/lib/definitions.mjs.map +1 -0
  80. package/dist/tools/lib/resolvers.d.mts +41 -0
  81. package/dist/tools/lib/resolvers.d.mts.map +1 -0
  82. package/dist/tools/lib/resolvers.mjs +43 -0
  83. package/dist/tools/lib/resolvers.mjs.map +1 -0
  84. package/dist/tools/lib/types.client.d.mts +13 -0
  85. package/dist/tools/lib/types.d.mts +33 -0
  86. package/dist/tools/resolvers/agent.server.d.mts +27 -0
  87. package/dist/tools/resolvers/agent.server.d.mts.map +1 -0
  88. package/dist/tools/resolvers/agent.server.mjs +44 -0
  89. package/dist/tools/resolvers/agent.server.mjs.map +1 -0
  90. package/dist/tools/resolvers/mcp.server.d.mts +31 -0
  91. package/dist/tools/resolvers/mcp.server.d.mts.map +1 -0
  92. package/dist/tools/resolvers/mcp.server.mjs +20 -0
  93. package/dist/tools/resolvers/mcp.server.mjs.map +1 -0
  94. package/dist/tools/server.d.mts +5 -0
  95. package/dist/tools/server.mjs +5 -0
  96. package/dist/tools/types.d.mts +33 -0
  97. package/dist/tools/types.d.mts.map +1 -0
  98. package/package.json +61 -0
  99. package/src/agents/entry.server.ts +7 -0
  100. package/src/agents/lib/definitions.server.ts +14 -0
  101. package/src/agents/lib/delegation.server.ts +33 -0
  102. package/src/agents/lib/instructions.server.ts +37 -0
  103. package/src/agents/lib/types.ts +32 -0
  104. package/src/chat/components/agent-activity.client.tsx +21 -0
  105. package/src/chat/components/chat-composer.client.tsx +379 -0
  106. package/src/chat/components/chat-message.client.tsx +166 -0
  107. package/src/chat/components/chat-thread.client.tsx +242 -0
  108. package/src/chat/components/message-part.client.tsx +59 -0
  109. package/src/chat/components/starter-prompts.client.tsx +49 -0
  110. package/src/chat/components/tool-call-card.client.tsx +78 -0
  111. package/src/chat/entry.client.ts +18 -0
  112. package/src/chat/entry.server.ts +5 -0
  113. package/src/chat/entry.ts +5 -0
  114. package/src/chat/lib/parts.ts +33 -0
  115. package/src/chat/lib/stream.server.ts +40 -0
  116. package/src/chat/lib/types.ts +20 -0
  117. package/src/entry.ts +24 -0
  118. package/src/mcp/entry.server.ts +2 -0
  119. package/src/mcp/lib/content.ts +131 -0
  120. package/src/mcp/lib/types.ts +28 -0
  121. package/src/styles.css +1 -0
  122. package/src/tools/entry.client.ts +7 -0
  123. package/src/tools/entry.server.ts +11 -0
  124. package/src/tools/lib/definitions.client.ts +21 -0
  125. package/src/tools/lib/definitions.ts +24 -0
  126. package/src/tools/lib/types.client.ts +11 -0
  127. package/src/tools/lib/types.ts +44 -0
  128. package/src/tools/resolvers/agent.server.ts +78 -0
  129. package/src/tools/resolvers/mcp.server.ts +40 -0
@@ -0,0 +1,131 @@
1
+ import type { McpResourceContent, McpToolResult } from "./types";
2
+
3
+ /**
4
+ * Creates a plain text MCP tool result.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * resolveMCPTool(getStatus, {
9
+ * content: ({ output }) => text(`Status: ${output.status}`),
10
+ * });
11
+ * ```
12
+ */
13
+ export function text(value: string, options?: { isError?: boolean }): McpToolResult {
14
+ return {
15
+ content: [{ type: "text", text: value }],
16
+ isError: options?.isError,
17
+ };
18
+ }
19
+
20
+ /**
21
+ * Creates a JSON MCP tool result with structured content preserved for clients that support it.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * resolveMCPTool(createProspect, {
26
+ * content: ({ output }) => json(output, { label: "Created prospect:" }),
27
+ * });
28
+ * ```
29
+ */
30
+ export function json<TValue>(
31
+ value: TValue,
32
+ options?: { label?: string; isError?: boolean },
33
+ ): McpToolResult<TValue> {
34
+ const serialized = JSON.stringify(value, null, 2);
35
+
36
+ return {
37
+ content: [
38
+ {
39
+ type: "text",
40
+ text: options?.label ? `${options.label}\n\n${serialized}` : serialized,
41
+ },
42
+ ],
43
+ structuredContent: value,
44
+ isError: options?.isError,
45
+ };
46
+ }
47
+
48
+ /**
49
+ * Creates an MCP resource result for text, blob, or URI-backed resources.
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * resolveMCPTool(getInvoice, {
54
+ * content: ({ output }) =>
55
+ * resource({ uri: output.uri, mimeType: "application/pdf" }),
56
+ * });
57
+ * ```
58
+ */
59
+ export function resource(value: McpResourceContent["resource"]): McpToolResult {
60
+ return {
61
+ content: [{ type: "resource", resource: value }],
62
+ };
63
+ }
64
+
65
+ /**
66
+ * Creates a markdown table MCP result and keeps the original rows as structured content.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * resolveMCPTool(listCustomers, {
71
+ * content: ({ output }) =>
72
+ * table(output.customers, {
73
+ * title: "Customers",
74
+ * columns: ["id", "name"],
75
+ * }),
76
+ * });
77
+ * ```
78
+ */
79
+ export function table<TRow extends Record<string, unknown>>(
80
+ rows: TRow[],
81
+ options?: {
82
+ columns?: Array<keyof TRow & string>;
83
+ emptyText?: string;
84
+ title?: string;
85
+ },
86
+ ): McpToolResult<{ columns: string[]; rows: TRow[] }> {
87
+ const columns = options?.columns ?? getColumns(rows);
88
+
89
+ if (rows.length === 0 || columns.length === 0) {
90
+ return {
91
+ content: [{ type: "text", text: options?.emptyText ?? "No results." }],
92
+ structuredContent: { columns, rows },
93
+ };
94
+ }
95
+
96
+ const header = `| ${columns.join(" | ")} |`;
97
+ const separator = `| ${columns.map(() => "---").join(" | ")} |`;
98
+ const body = rows.map(
99
+ (row) => `| ${columns.map((column) => formatCell(row[column])).join(" | ")} |`,
100
+ );
101
+ const table = [header, separator, ...body].join("\n");
102
+
103
+ return {
104
+ content: [{ type: "text", text: options?.title ? `${options.title}\n\n${table}` : table }],
105
+ structuredContent: { columns, rows },
106
+ };
107
+ }
108
+
109
+ function getColumns<TRow extends Record<string, unknown>>(rows: TRow[]) {
110
+ return Array.from(new Set(rows.flatMap((row) => Object.keys(row))));
111
+ }
112
+
113
+ function formatCell(value: unknown) {
114
+ if (value === null || value === undefined) {
115
+ return "";
116
+ }
117
+
118
+ if (value instanceof Date) {
119
+ return value.toISOString();
120
+ }
121
+
122
+ if (typeof value === "object") {
123
+ return escapeMarkdownTableCell(JSON.stringify(value));
124
+ }
125
+
126
+ return escapeMarkdownTableCell(String(value));
127
+ }
128
+
129
+ function escapeMarkdownTableCell(value: string) {
130
+ return value.replaceAll("|", "\\|").replaceAll("\n", " ");
131
+ }
@@ -0,0 +1,28 @@
1
+ export type McpTextContent = {
2
+ type: "text";
3
+ text: string;
4
+ };
5
+
6
+ export type McpImageContent = {
7
+ type: "image";
8
+ data: string;
9
+ mimeType: string;
10
+ };
11
+
12
+ export type McpResourceContent = {
13
+ type: "resource";
14
+ resource: {
15
+ uri: string;
16
+ mimeType?: string;
17
+ text?: string;
18
+ blob?: string;
19
+ };
20
+ };
21
+
22
+ export type McpContent = McpTextContent | McpImageContent | McpResourceContent;
23
+
24
+ export type McpToolResult<TStructuredContent = unknown> = {
25
+ content: McpContent[];
26
+ structuredContent?: TStructuredContent;
27
+ isError?: boolean;
28
+ };
package/src/styles.css ADDED
@@ -0,0 +1 @@
1
+ @source ".";
@@ -0,0 +1,7 @@
1
+ "use client";
2
+
3
+ /**
4
+ * Lib
5
+ */
6
+ export * from "./lib/definitions.client";
7
+ export * from "./lib/types.client";
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Lib
3
+ */
4
+ export * from "./lib/definitions";
5
+ export * from "./lib/types";
6
+
7
+ /**
8
+ * Resolvers
9
+ */
10
+ export * from "./resolvers/agent.server";
11
+ export * from "./resolvers/mcp.server";
@@ -0,0 +1,21 @@
1
+ import type { ToolClientDefinition, ToolClientSource } from "./types.client";
2
+
3
+ /**
4
+ * Defines how a server-side tool should be rendered in client chat UI.
5
+ * Use `import type` with the server tool to keep client bundles free of server code.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * import type { webSearchTool } from "./tool.server";
10
+ *
11
+ * export const webSearchToolClient = defineToolClient<typeof webSearchTool>({
12
+ * toolName: "web_search",
13
+ * render: (part) => <ToolCallCard part={part} title="Web Search" />,
14
+ * });
15
+ * ```
16
+ */
17
+ export function defineToolClient<const TTool extends ToolClientSource>(
18
+ definition: ToolClientDefinition<TTool>,
19
+ ) {
20
+ return definition;
21
+ }
@@ -0,0 +1,24 @@
1
+ import "server-cli-only";
2
+
3
+ import type { ToolContext, TulipToolDefinition, TulipToolSet } from "./types";
4
+
5
+ /**
6
+ * Defines the canonical Tulip tool shape without binding it to a specific transport.
7
+ * Resolvers adapt this definition for agents, MCP, UI, auditing, or permissions later.
8
+ */
9
+ export function defineTool<
10
+ const TName extends string,
11
+ TInput,
12
+ TOutput,
13
+ TContext extends ToolContext = ToolContext,
14
+ >(definition: TulipToolDefinition<TName, TInput, TOutput, TContext>) {
15
+ return definition;
16
+ }
17
+
18
+ /**
19
+ * Groups multiple Tulip tool definitions while preserving their literal names and types.
20
+ * Use this before resolving a shared set of tools for an agent or MCP endpoint.
21
+ */
22
+ export function defineToolSet<const TTools extends TulipToolSet>(tools: TTools) {
23
+ return tools;
24
+ }
@@ -0,0 +1,11 @@
1
+ import type { ReactNode } from "react";
2
+ import type { ToolChatPart } from "../../chat/lib/types";
3
+
4
+ export type ToolClientSource = {
5
+ name: string;
6
+ };
7
+
8
+ export type ToolClientDefinition<TTool extends ToolClientSource = ToolClientSource> = {
9
+ toolName: TTool["name"];
10
+ render: (part: ToolChatPart) => ReactNode;
11
+ };
@@ -0,0 +1,44 @@
1
+ import type { FlexibleSchema, ToolExecuteFunction, ToolExecutionOptions } from "ai";
2
+
3
+ export type ToolContext = Record<string, unknown>;
4
+
5
+ export type ToolConfirmation =
6
+ | false
7
+ | {
8
+ required?: boolean;
9
+ title?: string;
10
+ description?: string;
11
+ destructive?: boolean;
12
+ };
13
+
14
+ export type ToolAudit = {
15
+ action: string;
16
+ resource?: string;
17
+ severity?: "low" | "medium" | "high";
18
+ };
19
+
20
+ export type ToolDisplay = {
21
+ label?: string;
22
+ description?: string;
23
+ icon?: string;
24
+ };
25
+
26
+ export type TulipToolDefinition<
27
+ TName extends string = string,
28
+ TInput = unknown,
29
+ TOutput = unknown,
30
+ TContext extends ToolContext = ToolContext,
31
+ > = {
32
+ name: TName;
33
+ title: string;
34
+ description: string;
35
+ inputSchema: FlexibleSchema<TInput>;
36
+ outputSchema?: FlexibleSchema<TOutput>;
37
+ contextSchema?: FlexibleSchema<TContext>;
38
+ execute: ToolExecuteFunction<TInput, TOutput, TContext>;
39
+ };
40
+
41
+ export type TulipToolSet = Record<string, TulipToolDefinition>;
42
+
43
+ export type TulipToolExecutionOptions<TContext extends ToolContext = ToolContext> =
44
+ ToolExecutionOptions<TContext>;
@@ -0,0 +1,78 @@
1
+ import "server-cli-only";
2
+
3
+ import { type Tool, type ToolExecuteFunction, tool } from "ai";
4
+ import type {
5
+ ToolAudit,
6
+ ToolConfirmation,
7
+ ToolContext,
8
+ ToolDisplay,
9
+ TulipToolDefinition,
10
+ TulipToolSet,
11
+ } from "../lib/types";
12
+
13
+ export type AgentToolResolverOptions = {
14
+ title?: string;
15
+ description?: string;
16
+ permissions?: string[];
17
+ confirmation?: ToolConfirmation;
18
+ audit?: ToolAudit;
19
+ ui?: ToolDisplay;
20
+ };
21
+
22
+ /**
23
+ * Resolves a Tulip tool definition into an AI SDK tool for internal agents.
24
+ * Agent-specific metadata lives here so the base tool remains reusable by MCP and UI layers.
25
+ */
26
+ export function resolveAgentTool<TInput, TOutput, TContext extends ToolContext>(
27
+ definition: TulipToolDefinition<string, TInput, TOutput, TContext>,
28
+ options: AgentToolResolverOptions = {},
29
+ ): Tool<TInput, TOutput, TContext> {
30
+ return tool({
31
+ title: options.title ?? definition.title,
32
+ description: options.description ?? definition.description,
33
+ inputSchema: definition.inputSchema,
34
+ outputSchema: definition.outputSchema,
35
+ contextSchema: definition.contextSchema,
36
+ execute: definition.execute,
37
+ metadata: {
38
+ tulip: getSerializableToolMetadata(definition, options),
39
+ },
40
+ } as unknown as Tool<TInput, TOutput, TContext> & {
41
+ execute: ToolExecuteFunction<TInput, TOutput, TContext>;
42
+ });
43
+ }
44
+
45
+ /**
46
+ * Resolves a named set of Tulip tools into AI SDK tools.
47
+ * Per-tool resolver options can override labels, permissions, confirmation, audit, or UI metadata.
48
+ */
49
+ export function resolveAgentToolSet<TTools extends TulipToolSet>(
50
+ tools: TTools,
51
+ options: Partial<Record<keyof TTools, AgentToolResolverOptions>> = {},
52
+ ) {
53
+ return Object.fromEntries(
54
+ Object.entries(tools).map(([name, definition]) => [
55
+ name,
56
+ resolveAgentTool(definition, options[name]),
57
+ ]),
58
+ );
59
+ }
60
+
61
+ /**
62
+ * Produces serializable metadata that is attached to AI SDK tool calls.
63
+ * The chat UI and observability layers can read this without importing server-only code.
64
+ */
65
+ function getSerializableToolMetadata(
66
+ definition: Pick<TulipToolDefinition, "name" | "title" | "description">,
67
+ options: AgentToolResolverOptions,
68
+ ) {
69
+ return {
70
+ name: definition.name,
71
+ title: options.title ?? definition.title,
72
+ description: options.description ?? definition.description,
73
+ permissions: options.permissions,
74
+ confirmation: options.confirmation,
75
+ audit: options.audit,
76
+ ui: options.ui,
77
+ };
78
+ }
@@ -0,0 +1,40 @@
1
+ import "server-cli-only";
2
+
3
+ import type { McpToolResult } from "../../mcp/lib/types";
4
+ import type { TulipToolDefinition } from "../lib/types";
5
+
6
+ export type MCPToolResolverOptions<TInput, TOutput> = {
7
+ title?: string;
8
+ description?: string;
9
+ content?: (options: { input: TInput; output: TOutput }) => McpToolResult | Promise<McpToolResult>;
10
+ };
11
+
12
+ export type ResolvedMCPTool<TInput = unknown, TOutput = unknown> = {
13
+ name: string;
14
+ title: string;
15
+ description: string;
16
+ inputSchema: TulipToolDefinition<string, TInput, TOutput>["inputSchema"];
17
+ outputSchema?: TulipToolDefinition<string, TInput, TOutput>["outputSchema"];
18
+ resolveResult: (options: {
19
+ input: TInput;
20
+ output: TOutput;
21
+ }) => Promise<McpToolResult | undefined>;
22
+ };
23
+
24
+ /**
25
+ * Resolves a Tulip tool definition into an MCP-facing tool descriptor.
26
+ * MCP-specific labels and content formatting live here instead of in the base tool definition.
27
+ */
28
+ export function resolveMCPTool<TInput, TOutput>(
29
+ definition: TulipToolDefinition<string, TInput, TOutput>,
30
+ options: MCPToolResolverOptions<TInput, TOutput> = {},
31
+ ): ResolvedMCPTool<TInput, TOutput> {
32
+ return {
33
+ name: definition.name,
34
+ title: options.title ?? definition.title,
35
+ description: options.description ?? definition.description,
36
+ inputSchema: definition.inputSchema,
37
+ outputSchema: definition.outputSchema,
38
+ resolveResult: async (resultOptions) => options.content?.(resultOptions),
39
+ };
40
+ }