@poncho-ai/harness 0.2.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,14 @@
1
+
2
+ > @poncho-ai/harness@0.2.0 build /Users/cesar/Dev/latitude/poncho-ai/packages/harness
3
+ > tsup src/index.ts --format esm --dts
4
+
5
+ CLI Building entry: src/index.ts
6
+ CLI Using tsconfig: tsconfig.json
7
+ CLI tsup v8.5.1
8
+ CLI Target: es2022
9
+ ESM Build start
10
+ ESM dist/index.js 93.22 KB
11
+ ESM ⚡️ Build success in 31ms
12
+ DTS Build start
13
+ DTS ⚡️ Build success in 2649ms
14
+ DTS dist/index.d.ts 13.93 KB
@@ -0,0 +1,22 @@
1
+
2
+ > @poncho-ai/harness@0.1.0 test /Users/cesar/Dev/latitude/agentl/packages/harness
3
+ > vitest
4
+
5
+
6
+  RUN  v1.6.1 /Users/cesar/Dev/latitude/agentl/packages/harness
7
+
8
+ [event] step:completed {"type":"step:completed","step":1,"duration":1}
9
+ [event] step:started {"type":"step:started","step":2}
10
+ ✓ test/telemetry.test.ts  (3 tests) 5ms
11
+ ✓ test/state.test.ts  (4 tests) 20ms
12
+ ✓ test/mcp.test.ts  (1 test) 31ms
13
+ ✓ test/memory.test.ts  (4 tests) 11ms
14
+ ✓ test/agent-parser.test.ts  (2 tests) 8ms
15
+ ✓ test/model-factory.test.ts  (2 tests) 7ms
16
+ ✓ test/harness.test.ts  (15 tests) 57ms
17
+
18
+  Test Files  7 passed (7)
19
+  Tests  31 passed (31)
20
+  Start at  12:06:00
21
+  Duration  1.66s (transform 964ms, setup 0ms, collect 1.43s, tests 139ms, environment 1ms, prepare 3.37s)
22
+
package/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # @poncho-ai/harness
2
+
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Initial release of Poncho - an open framework for building and deploying AI agents.
8
+ - `@poncho-ai/sdk`: Core types and utilities for building Poncho skills
9
+ - `@poncho-ai/harness`: Agent execution runtime with conversation loop, tool dispatch, and streaming
10
+ - `@poncho-ai/client`: TypeScript client for calling deployed Poncho agents
11
+ - `@poncho-ai/cli`: CLI for building and deploying AI agents
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies []:
16
+ - @poncho-ai/sdk@0.2.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Latitude
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,416 @@
1
+ import { Message, ToolDefinition, RunInput, AgentEvent, RunResult, ToolContext } from '@poncho-ai/sdk';
2
+ export { ToolDefinition, defineTool } from '@poncho-ai/sdk';
3
+
4
+ interface AgentModelConfig {
5
+ provider: string;
6
+ name: string;
7
+ temperature?: number;
8
+ maxTokens?: number;
9
+ }
10
+ interface AgentLimitsConfig {
11
+ maxSteps?: number;
12
+ timeout?: number;
13
+ }
14
+ interface AgentFrontmatter {
15
+ name: string;
16
+ description?: string;
17
+ model?: AgentModelConfig;
18
+ limits?: AgentLimitsConfig;
19
+ }
20
+ interface ParsedAgent {
21
+ frontmatter: AgentFrontmatter;
22
+ body: string;
23
+ }
24
+ interface RuntimeRenderContext {
25
+ parameters?: Record<string, unknown>;
26
+ runtime?: {
27
+ workingDir?: string;
28
+ agentId?: string;
29
+ runId?: string;
30
+ environment?: string;
31
+ };
32
+ }
33
+ declare const parseAgentMarkdown: (content: string) => ParsedAgent;
34
+ declare const parseAgentFile: (workingDir: string) => Promise<ParsedAgent>;
35
+ declare const renderAgentPrompt: (agent: ParsedAgent, context?: RuntimeRenderContext) => string;
36
+
37
+ interface ConversationState {
38
+ runId: string;
39
+ messages: Message[];
40
+ updatedAt: number;
41
+ }
42
+ interface StateStore {
43
+ get(runId: string): Promise<ConversationState | undefined>;
44
+ set(state: ConversationState): Promise<void>;
45
+ delete(runId: string): Promise<void>;
46
+ }
47
+ interface Conversation {
48
+ conversationId: string;
49
+ title: string;
50
+ messages: Message[];
51
+ runtimeRunId?: string;
52
+ ownerId: string;
53
+ tenantId: string | null;
54
+ createdAt: number;
55
+ updatedAt: number;
56
+ }
57
+ interface ConversationStore {
58
+ list(ownerId?: string): Promise<Conversation[]>;
59
+ get(conversationId: string): Promise<Conversation | undefined>;
60
+ create(ownerId?: string, title?: string): Promise<Conversation>;
61
+ update(conversation: Conversation): Promise<void>;
62
+ rename(conversationId: string, title: string): Promise<Conversation | undefined>;
63
+ delete(conversationId: string): Promise<boolean>;
64
+ }
65
+ type StateProviderName = "local" | "memory" | "redis" | "upstash" | "dynamodb";
66
+ interface StateConfig {
67
+ provider?: StateProviderName;
68
+ ttl?: number;
69
+ url?: string;
70
+ token?: string;
71
+ table?: string;
72
+ region?: string;
73
+ }
74
+ declare class InMemoryStateStore implements StateStore {
75
+ private readonly store;
76
+ private readonly ttlMs?;
77
+ constructor(ttlSeconds?: number);
78
+ private isExpired;
79
+ get(runId: string): Promise<ConversationState | undefined>;
80
+ set(state: ConversationState): Promise<void>;
81
+ delete(runId: string): Promise<void>;
82
+ }
83
+ declare class InMemoryConversationStore implements ConversationStore {
84
+ private readonly conversations;
85
+ private readonly ttlMs?;
86
+ constructor(ttlSeconds?: number);
87
+ private isExpired;
88
+ private purgeExpired;
89
+ list(ownerId?: string): Promise<Conversation[]>;
90
+ get(conversationId: string): Promise<Conversation | undefined>;
91
+ create(ownerId?: string, title?: string): Promise<Conversation>;
92
+ update(conversation: Conversation): Promise<void>;
93
+ rename(conversationId: string, title: string): Promise<Conversation | undefined>;
94
+ delete(conversationId: string): Promise<boolean>;
95
+ }
96
+ declare const createStateStore: (config?: StateConfig, options?: {
97
+ workingDir?: string;
98
+ }) => StateStore;
99
+ declare const createConversationStore: (config?: StateConfig, options?: {
100
+ workingDir?: string;
101
+ }) => ConversationStore;
102
+
103
+ interface MainMemory {
104
+ content: string;
105
+ updatedAt: number;
106
+ }
107
+ interface MemoryConfig {
108
+ enabled?: boolean;
109
+ provider?: StateProviderName;
110
+ url?: string;
111
+ token?: string;
112
+ table?: string;
113
+ region?: string;
114
+ ttl?: number;
115
+ maxRecallConversations?: number;
116
+ }
117
+ interface MemoryStore {
118
+ getMainMemory(): Promise<MainMemory>;
119
+ updateMainMemory(input: {
120
+ content: string;
121
+ mode?: "replace" | "append";
122
+ }): Promise<MainMemory>;
123
+ }
124
+ declare const createMemoryStore: (agentId: string, config?: MemoryConfig, options?: {
125
+ workingDir?: string;
126
+ }) => MemoryStore;
127
+ declare const createMemoryTools: (store: MemoryStore, options?: {
128
+ maxRecallConversations?: number;
129
+ }) => ToolDefinition[];
130
+
131
+ interface RemoteMcpServerConfig {
132
+ name?: string;
133
+ url: string;
134
+ env?: string[];
135
+ timeoutMs?: number;
136
+ reconnectAttempts?: number;
137
+ reconnectDelayMs?: number;
138
+ }
139
+ interface McpConfig {
140
+ mcp?: RemoteMcpServerConfig[];
141
+ }
142
+ declare class LocalMcpBridge {
143
+ private readonly remoteServers;
144
+ private readonly rpcClients;
145
+ constructor(config: McpConfig | undefined);
146
+ loadTools(): Promise<ToolDefinition[]>;
147
+ startLocalServers(): Promise<void>;
148
+ stopLocalServers(): Promise<void>;
149
+ listServers(): RemoteMcpServerConfig[];
150
+ listRemoteServers(): RemoteMcpServerConfig[];
151
+ checkRemoteConnectivity(): Promise<Array<{
152
+ url: string;
153
+ ok: boolean;
154
+ error?: string;
155
+ }>>;
156
+ toSerializableConfig(): McpConfig;
157
+ getLocalServers(): never[];
158
+ private toToolDefinitions;
159
+ }
160
+
161
+ interface StorageConfig {
162
+ provider?: "local" | "memory" | "redis" | "upstash" | "dynamodb";
163
+ url?: string;
164
+ token?: string;
165
+ table?: string;
166
+ region?: string;
167
+ ttl?: number | {
168
+ conversations?: number;
169
+ memory?: number;
170
+ };
171
+ memory?: {
172
+ enabled?: boolean;
173
+ maxRecallConversations?: number;
174
+ };
175
+ }
176
+ type BuiltInToolToggles = {
177
+ list_directory?: boolean;
178
+ read_file?: boolean;
179
+ write_file?: boolean;
180
+ };
181
+ interface PonchoConfig extends McpConfig {
182
+ harness?: string;
183
+ tools?: {
184
+ defaults?: BuiltInToolToggles;
185
+ byEnvironment?: {
186
+ development?: BuiltInToolToggles;
187
+ staging?: BuiltInToolToggles;
188
+ production?: BuiltInToolToggles;
189
+ };
190
+ };
191
+ auth?: {
192
+ required?: boolean;
193
+ type?: "bearer" | "header" | "custom";
194
+ headerName?: string;
195
+ validate?: (token: string, req?: unknown) => Promise<boolean> | boolean;
196
+ };
197
+ state?: {
198
+ provider?: "local" | "memory" | "redis" | "upstash" | "dynamodb";
199
+ ttl?: number;
200
+ [key: string]: unknown;
201
+ };
202
+ memory?: MemoryConfig;
203
+ storage?: StorageConfig;
204
+ telemetry?: {
205
+ enabled?: boolean;
206
+ otlp?: string;
207
+ latitude?: {
208
+ apiKey?: string;
209
+ projectId?: string | number;
210
+ path?: string;
211
+ documentPath?: string;
212
+ };
213
+ handler?: (event: unknown) => Promise<void> | void;
214
+ };
215
+ skills?: Record<string, Record<string, unknown>>;
216
+ /** Extra directories (relative to project root) to scan for skills.
217
+ * `skills/` and `.poncho/skills/` are always scanned. */
218
+ skillPaths?: string[];
219
+ build?: {
220
+ vercel?: Record<string, unknown>;
221
+ docker?: Record<string, unknown>;
222
+ lambda?: Record<string, unknown>;
223
+ fly?: Record<string, unknown>;
224
+ };
225
+ }
226
+ declare const resolveStateConfig: (config: PonchoConfig | undefined) => StateConfig | undefined;
227
+ declare const resolveMemoryConfig: (config: PonchoConfig | undefined) => MemoryConfig | undefined;
228
+ declare const loadPonchoConfig: (workingDir: string) => Promise<PonchoConfig | undefined>;
229
+
230
+ declare const createDefaultTools: (workingDir: string) => ToolDefinition[];
231
+ declare const createWriteTool: (workingDir: string) => ToolDefinition;
232
+
233
+ interface HarnessOptions {
234
+ workingDir?: string;
235
+ environment?: "development" | "staging" | "production";
236
+ toolDefinitions?: ToolDefinition[];
237
+ approvalHandler?: (request: {
238
+ tool: string;
239
+ input: Record<string, unknown>;
240
+ runId: string;
241
+ step: number;
242
+ approvalId: string;
243
+ }) => Promise<boolean> | boolean;
244
+ }
245
+ interface HarnessRunOutput {
246
+ runId: string;
247
+ result: RunResult;
248
+ events: AgentEvent[];
249
+ messages: Message[];
250
+ }
251
+ declare class AgentHarness {
252
+ private readonly workingDir;
253
+ private readonly environment;
254
+ private modelClient;
255
+ private readonly dispatcher;
256
+ private readonly approvalHandler?;
257
+ private skillContextWindow;
258
+ private memoryStore?;
259
+ private parsedAgent?;
260
+ private mcpBridge?;
261
+ private getConfiguredToolFlag;
262
+ private isBuiltInToolEnabled;
263
+ private registerIfMissing;
264
+ private registerConfiguredBuiltInTools;
265
+ private shouldEnableWriteTool;
266
+ constructor(options?: HarnessOptions);
267
+ initialize(): Promise<void>;
268
+ shutdown(): Promise<void>;
269
+ listTools(): ToolDefinition[];
270
+ run(input: RunInput): AsyncGenerator<AgentEvent>;
271
+ runToCompletion(input: RunInput): Promise<HarnessRunOutput>;
272
+ }
273
+
274
+ interface LatitudeCaptureConfig {
275
+ apiKey?: string;
276
+ projectId?: string | number;
277
+ path?: string;
278
+ defaultPath?: string;
279
+ }
280
+ declare class LatitudeCapture {
281
+ private readonly apiKey?;
282
+ private telemetryPromise?;
283
+ private readonly projectId?;
284
+ private readonly path?;
285
+ constructor(config?: LatitudeCaptureConfig);
286
+ private initializeTelemetry;
287
+ capture<T>(fn: () => Promise<T>): Promise<T>;
288
+ }
289
+
290
+ interface ModelResponse {
291
+ text: string;
292
+ toolCalls: Array<{
293
+ id: string;
294
+ name: string;
295
+ input: Record<string, unknown>;
296
+ }>;
297
+ usage: {
298
+ input: number;
299
+ output: number;
300
+ };
301
+ rawContent: unknown[];
302
+ }
303
+ interface ModelCallInput {
304
+ systemPrompt: string;
305
+ messages: Message[];
306
+ tools: ToolDefinition[];
307
+ modelName: string;
308
+ temperature?: number;
309
+ maxTokens?: number;
310
+ }
311
+ interface ModelClientOptions {
312
+ latitudeCapture?: LatitudeCapture;
313
+ }
314
+ type ModelStreamEvent = {
315
+ type: "chunk";
316
+ content: string;
317
+ } | {
318
+ type: "final";
319
+ response: ModelResponse;
320
+ };
321
+ interface ModelClient {
322
+ generate(input: ModelCallInput): Promise<ModelResponse>;
323
+ generateStream?(input: ModelCallInput): AsyncGenerator<ModelStreamEvent>;
324
+ }
325
+
326
+ declare const createModelClient: (provider?: string, options?: ModelClientOptions) => ModelClient;
327
+
328
+ declare class OpenAiModelClient implements ModelClient {
329
+ private readonly client;
330
+ private readonly latitudeCapture;
331
+ constructor(apiKey?: string, options?: ModelClientOptions);
332
+ generateStream(input: ModelCallInput): AsyncGenerator<ModelStreamEvent>;
333
+ generate(input: ModelCallInput): Promise<ModelResponse>;
334
+ }
335
+
336
+ /**
337
+ * Resolve the full list of skill directories to scan.
338
+ * Merges the defaults with any extra paths provided via config.
339
+ */
340
+ declare const resolveSkillDirs: (workingDir: string, extraPaths?: string[]) => string[];
341
+ interface SkillMetadata {
342
+ /** Unique skill name from frontmatter. */
343
+ name: string;
344
+ /** What the skill does and when to use it. */
345
+ description: string;
346
+ /** Tool hints declared in frontmatter (spec `allowed-tools` or legacy `tools`). */
347
+ tools: string[];
348
+ /** Absolute path to the skill directory. */
349
+ skillDir: string;
350
+ /** Absolute path to the SKILL.md file. */
351
+ skillPath: string;
352
+ }
353
+ /**
354
+ * @deprecated Use {@link SkillMetadata} instead. Kept for backward compatibility.
355
+ */
356
+ type SkillContextEntry = SkillMetadata & {
357
+ instructions: string;
358
+ };
359
+ declare const loadSkillMetadata: (workingDir: string, extraSkillPaths?: string[]) => Promise<SkillMetadata[]>;
360
+ declare const buildSkillContextWindow: (skills: SkillMetadata[]) => string;
361
+ declare const loadSkillInstructions: (skill: SkillMetadata) => Promise<string>;
362
+ declare const readSkillResource: (skill: SkillMetadata, relativePath: string) => Promise<string>;
363
+ declare const loadSkillContext: (workingDir: string) => Promise<SkillContextEntry[]>;
364
+
365
+ /**
366
+ * Creates the built-in skill tools that implement progressive disclosure
367
+ * per the Agent Skills specification (https://agentskills.io/integrate-skills).
368
+ *
369
+ * - `activate_skill` — loads the full SKILL.md body on demand
370
+ * - `read_skill_resource` — reads a file from a skill directory (references, scripts, assets)
371
+ * - `list_skill_scripts` — lists runnable JavaScript/TypeScript scripts under scripts/
372
+ * - `run_skill_script` — executes a JavaScript/TypeScript module under scripts/
373
+ */
374
+ declare const createSkillTools: (skills: SkillMetadata[]) => ToolDefinition[];
375
+
376
+ interface TelemetryConfig {
377
+ enabled?: boolean;
378
+ otlp?: string;
379
+ latitude?: {
380
+ apiKey?: string;
381
+ projectId?: string | number;
382
+ path?: string;
383
+ documentPath?: string;
384
+ };
385
+ handler?: (event: AgentEvent) => Promise<void> | void;
386
+ }
387
+ declare class TelemetryEmitter {
388
+ private readonly config;
389
+ constructor(config?: TelemetryConfig);
390
+ emit(event: AgentEvent): Promise<void>;
391
+ private sendOtlp;
392
+ private sendLatitude;
393
+ }
394
+
395
+ interface ToolCall {
396
+ id: string;
397
+ name: string;
398
+ input: Record<string, unknown>;
399
+ }
400
+ interface ToolExecutionResult {
401
+ callId: string;
402
+ tool: string;
403
+ output?: unknown;
404
+ error?: string;
405
+ }
406
+ declare class ToolDispatcher {
407
+ private readonly tools;
408
+ register(tool: ToolDefinition): void;
409
+ registerMany(tools: ToolDefinition[]): void;
410
+ list(): ToolDefinition[];
411
+ get(name: string): ToolDefinition | undefined;
412
+ execute(call: ToolCall, context: ToolContext): Promise<ToolExecutionResult>;
413
+ executeBatch(calls: ToolCall[], context: ToolContext): Promise<ToolExecutionResult[]>;
414
+ }
415
+
416
+ export { type AgentFrontmatter, AgentHarness, type AgentLimitsConfig, type AgentModelConfig, type BuiltInToolToggles, type Conversation, type ConversationState, type ConversationStore, type HarnessOptions, type HarnessRunOutput, InMemoryConversationStore, InMemoryStateStore, LatitudeCapture, type LatitudeCaptureConfig, LocalMcpBridge, type MainMemory, type McpConfig, type MemoryConfig, type MemoryStore, type ModelCallInput, type ModelClient, type ModelClientOptions, type ModelResponse, type ModelStreamEvent, OpenAiModelClient, type ParsedAgent, type PonchoConfig, type RemoteMcpServerConfig, type RuntimeRenderContext, type SkillContextEntry, type SkillMetadata, type StateConfig, type StateProviderName, type StateStore, type StorageConfig, type TelemetryConfig, TelemetryEmitter, type ToolCall, ToolDispatcher, type ToolExecutionResult, buildSkillContextWindow, createConversationStore, createDefaultTools, createMemoryStore, createMemoryTools, createModelClient, createSkillTools, createStateStore, createWriteTool, loadPonchoConfig, loadSkillContext, loadSkillInstructions, loadSkillMetadata, parseAgentFile, parseAgentMarkdown, readSkillResource, renderAgentPrompt, resolveMemoryConfig, resolveSkillDirs, resolveStateConfig };