@geometra/agent 1.17.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.
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Main entry point for the Geometra agent runtime.
3
+ *
4
+ * `createAgentApp()` wires together a WebSocket server, reactive state, and
5
+ * a chat view so that building an LLM-powered agent UI is a single function call.
6
+ */
7
+ import type { AgentAppOptions, AgentApp } from './types.js';
8
+ /**
9
+ * Create a Geometra agent application.
10
+ *
11
+ * Sets up a WebSocket server with a reactive chat UI. The `onMessage` callback
12
+ * is invoked when the user submits text; use the provided helpers to stream a
13
+ * response back.
14
+ *
15
+ * ```ts
16
+ * const app = await createAgentApp({
17
+ * port: 3000,
18
+ * onMessage: async (text, { append, setStatus, done }) => {
19
+ * setStatus('thinking')
20
+ * for await (const chunk of myLLM(text)) append(chunk)
21
+ * done()
22
+ * },
23
+ * })
24
+ * ```
25
+ */
26
+ export declare function createAgentApp(options: AgentAppOptions): Promise<AgentApp>;
27
+ //# sourceMappingURL=agent-app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-app.d.ts","sourceRoot":"","sources":["../src/agent-app.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EACV,eAAe,EACf,QAAQ,EAKT,MAAM,YAAY,CAAA;AAEnB;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC,CAiHhF"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Main entry point for the Geometra agent runtime.
3
+ *
4
+ * `createAgentApp()` wires together a WebSocket server, reactive state, and
5
+ * a chat view so that building an LLM-powered agent UI is a single function call.
6
+ */
7
+ import { signal, batch, streamText } from '@geometra/core';
8
+ import { createServer } from '@geometra/server';
9
+ import { chatView } from './chat-view.js';
10
+ /**
11
+ * Create a Geometra agent application.
12
+ *
13
+ * Sets up a WebSocket server with a reactive chat UI. The `onMessage` callback
14
+ * is invoked when the user submits text; use the provided helpers to stream a
15
+ * response back.
16
+ *
17
+ * ```ts
18
+ * const app = await createAgentApp({
19
+ * port: 3000,
20
+ * onMessage: async (text, { append, setStatus, done }) => {
21
+ * setStatus('thinking')
22
+ * for await (const chunk of myLLM(text)) append(chunk)
23
+ * done()
24
+ * },
25
+ * })
26
+ * ```
27
+ */
28
+ export async function createAgentApp(options) {
29
+ // ---- State ---------------------------------------------------------------
30
+ const messages = signal([]);
31
+ const status = signal('idle');
32
+ const error = signal(null);
33
+ const streaming = streamText();
34
+ const state = {
35
+ messages,
36
+ status,
37
+ streamingText: streaming,
38
+ error,
39
+ };
40
+ // ---- System prompt -------------------------------------------------------
41
+ if (options.systemPrompt) {
42
+ messages.set([
43
+ {
44
+ role: 'system',
45
+ content: options.systemPrompt,
46
+ timestamp: new Date().toISOString(),
47
+ },
48
+ ]);
49
+ }
50
+ // ---- onMessage handler ---------------------------------------------------
51
+ function handleUserMessage(text) {
52
+ // Add user message
53
+ batch(() => {
54
+ const current = messages.peek();
55
+ messages.set([
56
+ ...current,
57
+ { role: 'user', content: text, timestamp: new Date().toISOString() },
58
+ ]);
59
+ error.set(null);
60
+ streaming.clear();
61
+ status.set('thinking');
62
+ });
63
+ server.update();
64
+ // Build callbacks for the agent
65
+ const callbacks = {
66
+ append(chunk) {
67
+ status.set('streaming');
68
+ streaming.append(chunk);
69
+ server.update();
70
+ },
71
+ set(text) {
72
+ status.set('streaming');
73
+ streaming.set(text);
74
+ server.update();
75
+ },
76
+ setStatus(s) {
77
+ status.set(s);
78
+ server.update();
79
+ },
80
+ done(metadata) {
81
+ const finalText = streaming.signal.peek();
82
+ streaming.done();
83
+ batch(() => {
84
+ if (finalText.length > 0) {
85
+ const current = messages.peek();
86
+ messages.set([
87
+ ...current,
88
+ {
89
+ role: 'assistant',
90
+ content: finalText,
91
+ timestamp: new Date().toISOString(),
92
+ metadata,
93
+ },
94
+ ]);
95
+ }
96
+ streaming.clear();
97
+ streaming.done(); // reset to not-streaming after clear
98
+ status.set('idle');
99
+ });
100
+ server.update();
101
+ },
102
+ };
103
+ // Invoke the user's handler (async-safe)
104
+ Promise.resolve()
105
+ .then(() => options.onMessage(text, callbacks))
106
+ .catch((err) => {
107
+ batch(() => {
108
+ status.set('error');
109
+ error.set(err instanceof Error ? err.message : String(err));
110
+ streaming.done();
111
+ });
112
+ server.update();
113
+ });
114
+ }
115
+ // ---- View ----------------------------------------------------------------
116
+ const viewFn = options.view
117
+ ? () => options.view(state)
118
+ : chatView(state, {
119
+ title: options.title,
120
+ onSubmit: handleUserMessage,
121
+ });
122
+ // ---- Server --------------------------------------------------------------
123
+ const server = await createServer(viewFn, {
124
+ port: options.port ?? 3000,
125
+ width: options.width ?? 800,
126
+ height: options.height ?? 'auto',
127
+ onConnection: options.onConnection,
128
+ onDisconnect: options.onDisconnect,
129
+ onError: options.onError,
130
+ });
131
+ return { server, state };
132
+ }
133
+ //# sourceMappingURL=agent-app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-app.js","sourceRoot":"","sources":["../src/agent-app.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Default chat view for the agent UI.
3
+ *
4
+ * Renders a message list with streaming response, status indicator, and
5
+ * input field. Fully built from `@geometra/core` and `@geometra/ui` primitives.
6
+ */
7
+ import type { UIElement } from '@geometra/core';
8
+ import type { AgentState } from './types.js';
9
+ export interface ChatViewOptions {
10
+ /** Header title (default: 'Agent'). */
11
+ title?: string;
12
+ /** Called when user submits a message. */
13
+ onSubmit?: (text: string) => void;
14
+ }
15
+ /**
16
+ * Build the default chat view. Returns a function `() => UIElement` suitable
17
+ * as a view for `createServer`.
18
+ */
19
+ export declare function chatView(state: AgentState, options?: ChatViewOptions): () => UIElement;
20
+ //# sourceMappingURL=chat-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-view.d.ts","sourceRoot":"","sources":["../src/chat-view.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAiB,MAAM,gBAAgB,CAAA;AAE9D,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,YAAY,CAAA;AAuEzD,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAClC;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,UAAU,EACjB,OAAO,GAAE,eAAoB,GAC5B,MAAM,SAAS,CAwIjB"}
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Default chat view for the agent UI.
3
+ *
4
+ * Renders a message list with streaming response, status indicator, and
5
+ * input field. Fully built from `@geometra/core` and `@geometra/ui` primitives.
6
+ */
7
+ import { box, text, signal } from '@geometra/core';
8
+ import { button, input } from '@geometra/ui';
9
+ // ---------------------------------------------------------------------------
10
+ // Helpers
11
+ // ---------------------------------------------------------------------------
12
+ function statusLabel(status) {
13
+ switch (status) {
14
+ case 'thinking':
15
+ return 'Thinking...';
16
+ case 'streaming':
17
+ return 'Responding...';
18
+ case 'tool-use':
19
+ return 'Using tool...';
20
+ case 'error':
21
+ return 'Error';
22
+ default:
23
+ return '';
24
+ }
25
+ }
26
+ function statusColor(status) {
27
+ switch (status) {
28
+ case 'thinking':
29
+ case 'streaming':
30
+ return '#38bdf8';
31
+ case 'tool-use':
32
+ return '#a78bfa';
33
+ case 'error':
34
+ return '#ef4444';
35
+ default:
36
+ return '#64748b';
37
+ }
38
+ }
39
+ function messageBubble(role, content) {
40
+ const isUser = role === 'user';
41
+ return box({
42
+ alignSelf: isUser ? 'flex-end' : 'flex-start',
43
+ maxWidth: '75%',
44
+ paddingLeft: 12,
45
+ paddingRight: 12,
46
+ paddingTop: 8,
47
+ paddingBottom: 8,
48
+ borderRadius: 12,
49
+ backgroundColor: isUser ? '#2563eb' : '#1e293b',
50
+ }, [
51
+ text({
52
+ text: content,
53
+ font: '14px Inter, system-ui',
54
+ lineHeight: 20,
55
+ color: isUser ? '#ffffff' : '#e2e8f0',
56
+ }),
57
+ ]);
58
+ }
59
+ // ---------------------------------------------------------------------------
60
+ // Input state (module-level signals for the controlled input)
61
+ // ---------------------------------------------------------------------------
62
+ const inputValue = signal('');
63
+ const inputFocused = signal(true);
64
+ const inputCaret = signal(0);
65
+ /**
66
+ * Build the default chat view. Returns a function `() => UIElement` suitable
67
+ * as a view for `createServer`.
68
+ */
69
+ export function chatView(state, options = {}) {
70
+ const title = options.title ?? 'Agent';
71
+ const handleSubmit = () => {
72
+ const val = inputValue.peek().trim();
73
+ if (val.length === 0)
74
+ return;
75
+ inputValue.set('');
76
+ inputCaret.set(0);
77
+ options.onSubmit?.(val);
78
+ };
79
+ const handleKeyDown = (e) => {
80
+ if (e.key === 'Enter' && !e.shiftKey) {
81
+ handleSubmit();
82
+ }
83
+ };
84
+ return () => {
85
+ const messages = state.messages.value;
86
+ const status = state.status.value;
87
+ const streaming = state.streamingText.value;
88
+ const error = state.error.value;
89
+ // Message list
90
+ const messageElements = messages.map((m) => messageBubble(m.role, m.content));
91
+ // Streaming response in progress
92
+ if (streaming.length > 0) {
93
+ messageElements.push(messageBubble('assistant', streaming));
94
+ }
95
+ // Status indicator
96
+ const statusText = statusLabel(status);
97
+ return box({
98
+ flexDirection: 'column',
99
+ width: '100%',
100
+ height: '100%',
101
+ backgroundColor: '#0f172a',
102
+ }, [
103
+ // Header
104
+ box({
105
+ paddingLeft: 16,
106
+ paddingRight: 16,
107
+ paddingTop: 12,
108
+ paddingBottom: 12,
109
+ borderColor: '#1e293b',
110
+ borderWidth: 1,
111
+ }, [
112
+ text({
113
+ text: title,
114
+ font: 'bold 16px Inter, system-ui',
115
+ lineHeight: 22,
116
+ color: '#f8fafc',
117
+ }),
118
+ ]),
119
+ // Messages area
120
+ box({
121
+ flexDirection: 'column',
122
+ flexGrow: 1,
123
+ gap: 8,
124
+ padding: 16,
125
+ overflow: 'scroll',
126
+ }, messageElements),
127
+ // Status bar
128
+ ...(statusText.length > 0
129
+ ? [
130
+ box({ paddingLeft: 16, paddingRight: 16, paddingBottom: 4 }, [
131
+ text({
132
+ text: statusText,
133
+ font: '12px Inter, system-ui',
134
+ lineHeight: 16,
135
+ color: statusColor(status),
136
+ }),
137
+ ]),
138
+ ]
139
+ : []),
140
+ // Error bar
141
+ ...(error
142
+ ? [
143
+ box({
144
+ paddingLeft: 16,
145
+ paddingRight: 16,
146
+ paddingBottom: 4,
147
+ }, [
148
+ text({
149
+ text: error,
150
+ font: '12px Inter, system-ui',
151
+ lineHeight: 16,
152
+ color: '#ef4444',
153
+ }),
154
+ ]),
155
+ ]
156
+ : []),
157
+ // Input area
158
+ box({
159
+ flexDirection: 'row',
160
+ gap: 8,
161
+ padding: 12,
162
+ borderColor: '#1e293b',
163
+ borderWidth: 1,
164
+ alignItems: 'center',
165
+ }, [
166
+ box({ flexGrow: 1 }, [
167
+ input(inputValue.value, 'Type a message...', {
168
+ focused: inputFocused.value,
169
+ caretOffset: inputCaret.value,
170
+ onCaretOffsetChange: (offset) => inputCaret.set(offset),
171
+ onKeyDown: handleKeyDown,
172
+ }),
173
+ ]),
174
+ button('Send', handleSubmit),
175
+ ]),
176
+ ]);
177
+ };
178
+ }
179
+ //# sourceMappingURL=chat-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-view.js","sourceRoot":"","sources":["../src/chat-view.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * `@geometra/agent` — AI agent UI runtime for Geometra.
4
+ *
5
+ * Provides `createAgentApp()` to wire up a WebSocket server with reactive
6
+ * chat state and a default chat view, plus building blocks for custom agent UIs.
7
+ */
8
+ export { createAgentApp } from './agent-app.js';
9
+ export { chatView } from './chat-view.js';
10
+ export type { ChatViewOptions } from './chat-view.js';
11
+ export type { AgentAppOptions, AgentApp, AgentState, AgentMessage, AgentCallbacks, AgentStatus, MessageRole, } from './types.js';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAG/C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAGrD,YAAY,EACV,eAAe,EACf,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,cAAc,EACd,WAAW,EACX,WAAW,GACZ,MAAM,YAAY,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * `@geometra/agent` — AI agent UI runtime for Geometra.
4
+ *
5
+ * Provides `createAgentApp()` to wire up a WebSocket server with reactive
6
+ * chat state and a default chat view, plus building blocks for custom agent UIs.
7
+ */
8
+ // Main entry
9
+ export { createAgentApp } from './agent-app.js';
10
+ // Default chat view (can be used standalone or swapped)
11
+ export { chatView } from './chat-view.js';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,aAAa;AACb,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAE/C,wDAAwD;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Types for the Geometra agent UI runtime.
3
+ */
4
+ import type { Signal } from '@geometra/core';
5
+ import type { StreamText } from '@geometra/core';
6
+ import type { UIElement } from '@geometra/core';
7
+ import type { TexturaServerOptions } from '@geometra/server';
8
+ export type MessageRole = 'user' | 'assistant' | 'system';
9
+ export interface AgentMessage {
10
+ readonly role: MessageRole;
11
+ readonly content: string;
12
+ /** ISO timestamp. */
13
+ readonly timestamp: string;
14
+ /** Optional metadata (tool names, model, etc.) */
15
+ readonly metadata?: Record<string, unknown>;
16
+ }
17
+ export type AgentStatus = 'idle' | 'thinking' | 'streaming' | 'tool-use' | 'error';
18
+ export interface AgentState {
19
+ /** Full message history. */
20
+ readonly messages: Signal<AgentMessage[]>;
21
+ /** Current agent status. */
22
+ readonly status: Signal<AgentStatus>;
23
+ /** Active streaming text (assistant's in-progress response). */
24
+ readonly streamingText: StreamText;
25
+ /** Last error message, if any. */
26
+ readonly error: Signal<string | null>;
27
+ }
28
+ export interface AgentCallbacks {
29
+ /** Append a text chunk to the streaming response. */
30
+ append(chunk: string): void;
31
+ /** Replace the streaming text entirely. */
32
+ set(text: string): void;
33
+ /** Update the agent status indicator. */
34
+ setStatus(status: AgentStatus): void;
35
+ /** Finalize the current response and add it to message history. */
36
+ done(metadata?: Record<string, unknown>): void;
37
+ }
38
+ export interface AgentAppOptions {
39
+ /**
40
+ * Called when the user submits a message. Use the callbacks to stream a
41
+ * response back.
42
+ */
43
+ onMessage: (text: string, callbacks: AgentCallbacks) => void | Promise<void>;
44
+ /** Port for the WebSocket server (default: 3000). */
45
+ port?: number;
46
+ /** Root layout width (default: 800). */
47
+ width?: number;
48
+ /** Root layout height (default: 'auto'). */
49
+ height?: number | 'auto';
50
+ /** System prompt shown as the first message (optional). */
51
+ systemPrompt?: string;
52
+ /** Custom view function. Receives agent state, returns UI tree. */
53
+ view?: (state: AgentState) => UIElement;
54
+ /** Title shown in the chat header (default: 'Agent'). */
55
+ title?: string;
56
+ /** Server hooks forwarded to createServer. */
57
+ onConnection?: TexturaServerOptions['onConnection'];
58
+ onDisconnect?: TexturaServerOptions['onDisconnect'];
59
+ onError?: TexturaServerOptions['onError'];
60
+ }
61
+ export interface AgentApp {
62
+ /** The underlying Geometra server. */
63
+ readonly server: {
64
+ update(): void;
65
+ broadcastData(channel: string, payload: unknown): void;
66
+ close(): void;
67
+ };
68
+ /** Reactive agent state — read or mutate from outside. */
69
+ readonly state: AgentState;
70
+ }
71
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AAM5D,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAA;AAEzD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,qBAAqB;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,kDAAkD;IAClD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC5C;AAED,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,OAAO,CAAA;AAMlF,MAAM,WAAW,UAAU;IACzB,4BAA4B;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAA;IACzC,4BAA4B;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,CAAA;IACpC,gEAAgE;IAChE,QAAQ,CAAC,aAAa,EAAE,UAAU,CAAA;IAClC,kCAAkC;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;CACtC;AAMD,MAAM,WAAW,cAAc;IAC7B,qDAAqD;IACrD,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,2CAA2C;IAC3C,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,yCAAyC;IACzC,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAA;IACpC,mEAAmE;IACnE,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;CAC/C;AAMD,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAE5E,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACxB,2DAA2D;IAC3D,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,mEAAmE;IACnE,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,SAAS,CAAA;IACvC,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,8CAA8C;IAC9C,YAAY,CAAC,EAAE,oBAAoB,CAAC,cAAc,CAAC,CAAA;IACnD,YAAY,CAAC,EAAE,oBAAoB,CAAC,cAAc,CAAC,CAAA;IACnD,OAAO,CAAC,EAAE,oBAAoB,CAAC,SAAS,CAAC,CAAA;CAC1C;AAED,MAAM,WAAW,QAAQ;IACvB,sCAAsC;IACtC,QAAQ,CAAC,MAAM,EAAE;QAAE,MAAM,IAAI,IAAI,CAAC;QAAC,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;QAAC,KAAK,IAAI,IAAI,CAAA;KAAE,CAAA;IAC1G,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;CAC3B"}
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Types for the Geometra agent UI runtime.
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@geometra/agent",
3
+ "version": "1.17.0",
4
+ "description": "AI agent UI runtime — wire up LLM agents with server-streamed Geometra UIs",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/razroo/geometra",
10
+ "directory": "packages/agent"
11
+ },
12
+ "homepage": "https://razroo.github.io/geometra",
13
+ "keywords": [
14
+ "geometra",
15
+ "agent",
16
+ "ai",
17
+ "llm",
18
+ "server-driven-ui"
19
+ ],
20
+ "main": "./dist/index.js",
21
+ "types": "./dist/index.d.ts",
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/index.d.ts",
25
+ "import": "./dist/index.js"
26
+ }
27
+ },
28
+ "files": [
29
+ "dist"
30
+ ],
31
+ "scripts": {
32
+ "build": "rm -rf dist && tsc -p tsconfig.build.json",
33
+ "check": "tsc --noEmit"
34
+ },
35
+ "dependencies": {
36
+ "@geometra/core": "^1.17.0",
37
+ "@geometra/server": "^1.17.0",
38
+ "@geometra/ui": "^1.17.0"
39
+ }
40
+ }