@poncho-ai/harness 0.14.1 → 0.14.2
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/.turbo/turbo-build.log +5 -5
- package/.turbo/turbo-lint.log +6 -0
- package/.turbo/turbo-test.log +137 -0
- package/CHANGELOG.md +9 -0
- package/dist/index.d.ts +34 -17
- package/dist/index.js +84 -40
- package/package.json +2 -2
- package/src/config.ts +13 -8
- package/src/harness.ts +53 -30
- package/src/latitude-capture.ts +9 -10
- package/src/memory.ts +8 -13
- package/src/model-factory.ts +13 -6
- package/src/state.ts +14 -12
- package/src/telemetry.ts +2 -2
- package/test/telemetry.test.ts +3 -3
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @poncho-ai/harness@0.14.
|
|
2
|
+
> @poncho-ai/harness@0.14.2 build /Users/cesar/Dev/latitude/poncho-ai/packages/harness
|
|
3
3
|
> tsup src/index.ts --format esm --dts
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
[34mCLI[39m tsup v8.5.1
|
|
8
8
|
[34mCLI[39m Target: es2022
|
|
9
9
|
[34mESM[39m Build start
|
|
10
|
-
[32mESM[39m [1mdist/index.js [22m[
|
|
11
|
-
[32mESM[39m ⚡️ Build success in
|
|
10
|
+
[32mESM[39m [1mdist/index.js [22m[32m177.01 KB[39m
|
|
11
|
+
[32mESM[39m ⚡️ Build success in 73ms
|
|
12
12
|
[34mDTS[39m Build start
|
|
13
|
-
[32mDTS[39m ⚡️ Build success in
|
|
14
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[32m21.
|
|
13
|
+
[32mDTS[39m ⚡️ Build success in 3459ms
|
|
14
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m21.71 KB[39m
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
|
|
2
|
+
> @poncho-ai/harness@0.14.0 test /Users/cesar/Dev/latitude/poncho-ai/packages/harness
|
|
3
|
+
> vitest
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
[7m[1m[36m RUN [39m[22m[27m [36mv1.6.1[39m [90m/Users/cesar/Dev/latitude/poncho-ai/packages/harness[39m
|
|
7
|
+
|
|
8
|
+
[event] step:completed {"type":"step:completed","step":1,"duration":1}
|
|
9
|
+
[event] step:started {"type":"step:started","step":2}
|
|
10
|
+
[32m✓[39m test/telemetry.test.ts [2m ([22m[2m3 tests[22m[2m)[22m[90m 11[2mms[22m[39m
|
|
11
|
+
[32m✓[39m test/schema-converter.test.ts [2m ([22m[2m27 tests[22m[2m)[22m[90m 21[2mms[22m[39m
|
|
12
|
+
[90mstdout[2m | test/mcp.test.ts[2m > [22m[2mmcp bridge protocol transports[2m > [22m[2mdiscovers and calls tools over streamable HTTP[22m[39m
|
|
13
|
+
[poncho][mcp] {"event":"catalog.loaded","server":"remote","discoveredCount":1}
|
|
14
|
+
[poncho][mcp] {"event":"tools.selected","requestedPatternCount":1,"registeredCount":1,"filteredByPolicyCount":0,"filteredByIntentCount":0}
|
|
15
|
+
|
|
16
|
+
[90mstdout[2m | test/mcp.test.ts[2m > [22m[2mmcp bridge protocol transports[2m > [22m[2mselects discovered tools by requested patterns[22m[39m
|
|
17
|
+
[poncho][mcp] {"event":"catalog.loaded","server":"remote","discoveredCount":2}
|
|
18
|
+
[poncho][mcp] {"event":"tools.selected","requestedPatternCount":1,"registeredCount":1,"filteredByPolicyCount":0,"filteredByIntentCount":1}
|
|
19
|
+
[poncho][mcp] {"event":"tools.selected","requestedPatternCount":1,"registeredCount":2,"filteredByPolicyCount":0,"filteredByIntentCount":0}
|
|
20
|
+
|
|
21
|
+
[90mstdout[2m | test/mcp.test.ts[2m > [22m[2mmcp bridge protocol transports[2m > [22m[2mskips discovery when bearer token env value is missing[22m[39m
|
|
22
|
+
[poncho][mcp] {"event":"tools.selected","requestedPatternCount":1,"registeredCount":0,"filteredByPolicyCount":0,"filteredByIntentCount":0}
|
|
23
|
+
|
|
24
|
+
[90mstderr[2m | test/mcp.test.ts[2m > [22m[2mmcp bridge protocol transports[2m > [22m[2mskips discovery when bearer token env value is missing[22m[39m
|
|
25
|
+
[poncho][mcp] {"event":"auth.token_missing","server":"remote","tokenEnv":"MISSING_TOKEN_ENV"}
|
|
26
|
+
|
|
27
|
+
[90mstdout[2m | test/mcp.test.ts[2m > [22m[2mmcp bridge protocol transports[2m > [22m[2mreturns actionable errors for 403 permission failures[22m[39m
|
|
28
|
+
[poncho][mcp] {"event":"catalog.loaded","server":"remote","discoveredCount":1}
|
|
29
|
+
[poncho][mcp] {"event":"tools.selected","requestedPatternCount":1,"registeredCount":1,"filteredByPolicyCount":0,"filteredByIntentCount":0}
|
|
30
|
+
|
|
31
|
+
[32m✓[39m test/mcp.test.ts [2m ([22m[2m6 tests[22m[2m)[22m[33m 516[2mms[22m[39m
|
|
32
|
+
[32m✓[39m test/agent-parser.test.ts [2m ([22m[2m10 tests[22m[2m)[22m[90m 130[2mms[22m[39m
|
|
33
|
+
[32m✓[39m test/memory.test.ts [2m ([22m[2m4 tests[22m[2m)[22m[90m 192[2mms[22m[39m
|
|
34
|
+
[32m✓[39m test/state.test.ts [2m ([22m[2m5 tests[22m[2m)[22m[90m 294[2mms[22m[39m
|
|
35
|
+
[32m✓[39m test/model-factory.test.ts [2m ([22m[2m4 tests[22m[2m)[22m[90m 8[2mms[22m[39m
|
|
36
|
+
[32m✓[39m test/agent-identity.test.ts [2m ([22m[2m2 tests[22m[2m)[22m[90m 33[2mms[22m[39m
|
|
37
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2mregisters default filesystem tools[22m[39m
|
|
38
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"initialize","requestedPatterns":[]}
|
|
39
|
+
|
|
40
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2mdisables write_file by default in production environment[22m[39m
|
|
41
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"initialize","requestedPatterns":[]}
|
|
42
|
+
|
|
43
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2mallows disabling built-in tools via poncho.config.js[22m[39m
|
|
44
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"initialize","requestedPatterns":[]}
|
|
45
|
+
|
|
46
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2msupports per-environment tool overrides[22m[39m
|
|
47
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"initialize","requestedPatterns":[]}
|
|
48
|
+
|
|
49
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2msupports per-environment tool overrides[22m[39m
|
|
50
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"initialize","requestedPatterns":[]}
|
|
51
|
+
|
|
52
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2mdoes not auto-register exported tool objects from skill scripts[22m[39m
|
|
53
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"initialize","requestedPatterns":[]}
|
|
54
|
+
|
|
55
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2mrefreshes skill metadata and tools in development mode[22m[39m
|
|
56
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"initialize","requestedPatterns":[]}
|
|
57
|
+
|
|
58
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2mrefreshes skill metadata and tools in development mode[22m[39m
|
|
59
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"skills:changed","requestedPatterns":[]}
|
|
60
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"activate:beta","requestedPatterns":[]}
|
|
61
|
+
|
|
62
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2mprunes removed active skills after refresh in development mode[22m[39m
|
|
63
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"initialize","requestedPatterns":[]}
|
|
64
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"activate:obsolete","requestedPatterns":[]}
|
|
65
|
+
|
|
66
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2mprunes removed active skills after refresh in development mode[22m[39m
|
|
67
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"skills:changed","requestedPatterns":[]}
|
|
68
|
+
|
|
69
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2mdoes not refresh skills outside development mode[22m[39m
|
|
70
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"initialize","requestedPatterns":[]}
|
|
71
|
+
|
|
72
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2mclears active skills when skill metadata changes in development mode[22m[39m
|
|
73
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"initialize","requestedPatterns":[]}
|
|
74
|
+
|
|
75
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2mclears active skills when skill metadata changes in development mode[22m[39m
|
|
76
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"activate:alpha","requestedPatterns":[]}
|
|
77
|
+
|
|
78
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2mclears active skills when skill metadata changes in development mode[22m[39m
|
|
79
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"skills:changed","requestedPatterns":[]}
|
|
80
|
+
|
|
81
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2mlists skill scripts through list_skill_scripts[22m[39m
|
|
82
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"initialize","requestedPatterns":[]}
|
|
83
|
+
|
|
84
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2mruns JavaScript/TypeScript skill scripts through run_skill_script[22m[39m
|
|
85
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"initialize","requestedPatterns":[]}
|
|
86
|
+
|
|
87
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2mruns AGENT-scope scripts from root scripts directory[22m[39m
|
|
88
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"initialize","requestedPatterns":[]}
|
|
89
|
+
|
|
90
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2mblocks path traversal in run_skill_script[22m[39m
|
|
91
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"initialize","requestedPatterns":[]}
|
|
92
|
+
|
|
93
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2mrequires allowed-tools entries for non-standard script directories[22m[39m
|
|
94
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"initialize","requestedPatterns":[]}
|
|
95
|
+
|
|
96
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2mregisters MCP tools dynamically for stacked active skills and supports deactivation[22m[39m
|
|
97
|
+
[poncho][mcp] {"event":"catalog.loaded","server":"remote","discoveredCount":2}
|
|
98
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"initialize","requestedPatterns":[]}
|
|
99
|
+
[poncho][mcp] {"event":"tools.selected","requestedPatternCount":1,"registeredCount":1,"filteredByPolicyCount":0,"filteredByIntentCount":1}
|
|
100
|
+
[poncho][mcp] {"event":"tools.refreshed","reason":"activate:skill-a","requestedPatterns":["remote/a"],"registeredCount":1,"activeSkills":["skill-a"]}
|
|
101
|
+
[poncho][mcp] {"event":"tools.selected","requestedPatternCount":2,"registeredCount":2,"filteredByPolicyCount":0,"filteredByIntentCount":0}
|
|
102
|
+
[poncho][mcp] {"event":"tools.refreshed","reason":"activate:skill-b","requestedPatterns":["remote/a","remote/b"],"registeredCount":2,"activeSkills":["skill-a","skill-b"]}
|
|
103
|
+
[poncho][mcp] {"event":"tools.selected","requestedPatternCount":1,"registeredCount":1,"filteredByPolicyCount":0,"filteredByIntentCount":1}
|
|
104
|
+
[poncho][mcp] {"event":"tools.refreshed","reason":"deactivate:skill-a","requestedPatterns":["remote/b"],"registeredCount":1,"activeSkills":["skill-b"]}
|
|
105
|
+
|
|
106
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2msupports flat tool access config format[22m[39m
|
|
107
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"initialize","requestedPatterns":[]}
|
|
108
|
+
|
|
109
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2mflat tool access takes priority over legacy defaults[22m[39m
|
|
110
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"initialize","requestedPatterns":[]}
|
|
111
|
+
|
|
112
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2mbyEnvironment overrides flat tool access[22m[39m
|
|
113
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"initialize","requestedPatterns":[]}
|
|
114
|
+
|
|
115
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2mregisterTools skips tools disabled via config[22m[39m
|
|
116
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"initialize","requestedPatterns":[]}
|
|
117
|
+
|
|
118
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2mapproval access level registers the tool but marks it for approval[22m[39m
|
|
119
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"initialize","requestedPatterns":[]}
|
|
120
|
+
|
|
121
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2mtools without approval config do not require approval[22m[39m
|
|
122
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"initialize","requestedPatterns":[]}
|
|
123
|
+
|
|
124
|
+
[90mstdout[2m | test/harness.test.ts[2m > [22m[2magent harness[2m > [22m[2mallows in-flight MCP calls to finish after skill deactivation[22m[39m
|
|
125
|
+
[poncho][mcp] {"event":"catalog.loaded","server":"remote","discoveredCount":1}
|
|
126
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"initialize","requestedPatterns":[]}
|
|
127
|
+
[poncho][mcp] {"event":"tools.selected","requestedPatternCount":1,"registeredCount":1,"filteredByPolicyCount":0,"filteredByIntentCount":0}
|
|
128
|
+
[poncho][mcp] {"event":"tools.refreshed","reason":"activate:skill-slow","requestedPatterns":["remote/slow"],"registeredCount":1,"activeSkills":["skill-slow"]}
|
|
129
|
+
[poncho][mcp] {"event":"tools.cleared","reason":"deactivate:skill-slow","requestedPatterns":[]}
|
|
130
|
+
|
|
131
|
+
[32m✓[39m test/harness.test.ts [2m ([22m[2m25 tests[22m[2m)[22m[33m 429[2mms[22m[39m
|
|
132
|
+
|
|
133
|
+
[2m Test Files [22m [1m[32m9 passed[39m[22m[90m (9)[39m
|
|
134
|
+
[2m Tests [22m [1m[32m86 passed[39m[22m[90m (86)[39m
|
|
135
|
+
[2m Start at [22m 10:02:54
|
|
136
|
+
[2m Duration [22m 4.19s[2m (transform 2.16s, setup 0ms, collect 7.51s, tests 1.63s, environment 1ms, prepare 1.97s)[22m
|
|
137
|
+
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @poncho-ai/harness
|
|
2
2
|
|
|
3
|
+
## 0.14.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`1f47bb4`](https://github.com/cesr/poncho-ai/commit/1f47bb49e5d48dc17644172012b057190b316469) Thanks [@cesr](https://github.com/cesr)! - Add conversation rename via double-click on the title in the web UI, standardize all credential config fields to the `*Env` naming pattern, and sync the init README template with the repo README.
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`1f47bb4`](https://github.com/cesr/poncho-ai/commit/1f47bb49e5d48dc17644172012b057190b316469)]:
|
|
10
|
+
- @poncho-ai/sdk@1.0.3
|
|
11
|
+
|
|
3
12
|
## 0.14.1
|
|
4
13
|
|
|
5
14
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -111,8 +111,8 @@ type StateProviderName = "local" | "memory" | "redis" | "upstash" | "dynamodb";
|
|
|
111
111
|
interface StateConfig {
|
|
112
112
|
provider?: StateProviderName;
|
|
113
113
|
ttl?: number;
|
|
114
|
-
|
|
115
|
-
|
|
114
|
+
urlEnv?: string;
|
|
115
|
+
tokenEnv?: string;
|
|
116
116
|
table?: string;
|
|
117
117
|
region?: string;
|
|
118
118
|
}
|
|
@@ -154,8 +154,8 @@ interface MainMemory {
|
|
|
154
154
|
interface MemoryConfig {
|
|
155
155
|
enabled?: boolean;
|
|
156
156
|
provider?: StateProviderName;
|
|
157
|
-
|
|
158
|
-
|
|
157
|
+
urlEnv?: string;
|
|
158
|
+
tokenEnv?: string;
|
|
159
159
|
table?: string;
|
|
160
160
|
region?: string;
|
|
161
161
|
ttl?: number;
|
|
@@ -218,8 +218,8 @@ declare class LocalMcpBridge {
|
|
|
218
218
|
|
|
219
219
|
interface StorageConfig {
|
|
220
220
|
provider?: "local" | "memory" | "redis" | "upstash" | "dynamodb";
|
|
221
|
-
|
|
222
|
-
|
|
221
|
+
urlEnv?: string;
|
|
222
|
+
tokenEnv?: string;
|
|
223
223
|
table?: string;
|
|
224
224
|
region?: string;
|
|
225
225
|
ttl?: number | {
|
|
@@ -274,6 +274,7 @@ interface PonchoConfig extends McpConfig {
|
|
|
274
274
|
required?: boolean;
|
|
275
275
|
type?: "bearer" | "header" | "custom";
|
|
276
276
|
headerName?: string;
|
|
277
|
+
tokenEnv?: string;
|
|
277
278
|
validate?: (token: string, req?: unknown) => Promise<boolean> | boolean;
|
|
278
279
|
};
|
|
279
280
|
state?: {
|
|
@@ -283,12 +284,20 @@ interface PonchoConfig extends McpConfig {
|
|
|
283
284
|
};
|
|
284
285
|
memory?: MemoryConfig;
|
|
285
286
|
storage?: StorageConfig;
|
|
287
|
+
providers?: {
|
|
288
|
+
openai?: {
|
|
289
|
+
apiKeyEnv?: string;
|
|
290
|
+
};
|
|
291
|
+
anthropic?: {
|
|
292
|
+
apiKeyEnv?: string;
|
|
293
|
+
};
|
|
294
|
+
};
|
|
286
295
|
telemetry?: {
|
|
287
296
|
enabled?: boolean;
|
|
288
297
|
otlp?: string;
|
|
289
298
|
latitude?: {
|
|
290
|
-
|
|
291
|
-
|
|
299
|
+
apiKeyEnv?: string;
|
|
300
|
+
projectIdEnv?: string;
|
|
292
301
|
path?: string;
|
|
293
302
|
documentPath?: string;
|
|
294
303
|
};
|
|
@@ -363,12 +372,20 @@ type ModelProviderFactory = (modelName: string) => LanguageModel;
|
|
|
363
372
|
* resolve via the base prefix. Longest match wins.
|
|
364
373
|
*/
|
|
365
374
|
declare const getModelContextWindow: (modelName: string) => number;
|
|
375
|
+
interface ProviderConfig {
|
|
376
|
+
openai?: {
|
|
377
|
+
apiKeyEnv?: string;
|
|
378
|
+
};
|
|
379
|
+
anthropic?: {
|
|
380
|
+
apiKeyEnv?: string;
|
|
381
|
+
};
|
|
382
|
+
}
|
|
366
383
|
/**
|
|
367
|
-
* Creates a model provider factory for the specified AI provider
|
|
368
|
-
*
|
|
369
|
-
*
|
|
384
|
+
* Creates a model provider factory for the specified AI provider.
|
|
385
|
+
* API keys are read from environment variables; override the env var
|
|
386
|
+
* name via the `providers` config in `poncho.config.js`.
|
|
370
387
|
*/
|
|
371
|
-
declare const createModelProvider: (provider?: string) => ModelProviderFactory;
|
|
388
|
+
declare const createModelProvider: (provider?: string, config?: ProviderConfig) => ModelProviderFactory;
|
|
372
389
|
|
|
373
390
|
interface ToolCall {
|
|
374
391
|
id: string;
|
|
@@ -489,8 +506,8 @@ declare class AgentHarness {
|
|
|
489
506
|
* Vercel AI SDK support.
|
|
490
507
|
*/
|
|
491
508
|
interface LatitudeCaptureConfig {
|
|
492
|
-
|
|
493
|
-
|
|
509
|
+
apiKeyEnv?: string;
|
|
510
|
+
projectIdEnv?: string;
|
|
494
511
|
path?: string;
|
|
495
512
|
defaultPath?: string;
|
|
496
513
|
}
|
|
@@ -585,8 +602,8 @@ interface TelemetryConfig {
|
|
|
585
602
|
enabled?: boolean;
|
|
586
603
|
otlp?: string;
|
|
587
604
|
latitude?: {
|
|
588
|
-
|
|
589
|
-
|
|
605
|
+
apiKeyEnv?: string;
|
|
606
|
+
projectIdEnv?: string;
|
|
590
607
|
path?: string;
|
|
591
608
|
documentPath?: string;
|
|
592
609
|
};
|
|
@@ -599,4 +616,4 @@ declare class TelemetryEmitter {
|
|
|
599
616
|
private sendOtlp;
|
|
600
617
|
}
|
|
601
618
|
|
|
602
|
-
export { type AgentFrontmatter, AgentHarness, type AgentIdentity, type AgentLimitsConfig, type AgentModelConfig, type BuiltInToolToggles, type Conversation, type ConversationState, type ConversationStore, type CronJobConfig, type HarnessOptions, type HarnessRunOutput, InMemoryConversationStore, InMemoryStateStore, LatitudeCapture, type LatitudeCaptureConfig, LocalMcpBridge, LocalUploadStore, type MainMemory, type McpConfig, type MemoryConfig, type MemoryStore, type MessagingChannelConfig, type ModelProviderFactory, PONCHO_UPLOAD_SCHEME, type ParsedAgent, type PonchoConfig, type RemoteMcpServerConfig, type RuntimeRenderContext, S3UploadStore, STORAGE_SCHEMA_VERSION, type SkillContextEntry, type SkillMetadata, type StateConfig, type StateProviderName, type StateStore, type StorageConfig, type TelemetryConfig, TelemetryEmitter, type ToolAccess, type ToolCall, ToolDispatcher, type ToolExecutionResult, type UploadStore, type UploadsConfig, VercelBlobUploadStore, buildAgentDirectoryName, buildSkillContextWindow, createConversationStore, createDefaultTools, createMemoryStore, createMemoryTools, createModelProvider, createSkillTools, createStateStore, createUploadStore, createWriteTool, deriveUploadKey, ensureAgentIdentity, generateAgentId, getAgentStoreDirectory, getModelContextWindow, getPonchoStoreRoot, jsonSchemaToZod, loadPonchoConfig, loadSkillContext, loadSkillInstructions, loadSkillMetadata, normalizeScriptPolicyPath, parseAgentFile, parseAgentMarkdown, readSkillResource, renderAgentPrompt, resolveAgentIdentity, resolveMemoryConfig, resolveSkillDirs, resolveStateConfig, slugifyStorageComponent };
|
|
619
|
+
export { type AgentFrontmatter, AgentHarness, type AgentIdentity, type AgentLimitsConfig, type AgentModelConfig, type BuiltInToolToggles, type Conversation, type ConversationState, type ConversationStore, type CronJobConfig, type HarnessOptions, type HarnessRunOutput, InMemoryConversationStore, InMemoryStateStore, LatitudeCapture, type LatitudeCaptureConfig, LocalMcpBridge, LocalUploadStore, type MainMemory, type McpConfig, type MemoryConfig, type MemoryStore, type MessagingChannelConfig, type ModelProviderFactory, PONCHO_UPLOAD_SCHEME, type ParsedAgent, type PonchoConfig, type ProviderConfig, type RemoteMcpServerConfig, type RuntimeRenderContext, S3UploadStore, STORAGE_SCHEMA_VERSION, type SkillContextEntry, type SkillMetadata, type StateConfig, type StateProviderName, type StateStore, type StorageConfig, type TelemetryConfig, TelemetryEmitter, type ToolAccess, type ToolCall, ToolDispatcher, type ToolExecutionResult, type UploadStore, type UploadsConfig, VercelBlobUploadStore, buildAgentDirectoryName, buildSkillContextWindow, createConversationStore, createDefaultTools, createMemoryStore, createMemoryTools, createModelProvider, createSkillTools, createStateStore, createUploadStore, createWriteTool, deriveUploadKey, ensureAgentIdentity, generateAgentId, getAgentStoreDirectory, getModelContextWindow, getPonchoStoreRoot, jsonSchemaToZod, loadPonchoConfig, loadSkillContext, loadSkillInstructions, loadSkillMetadata, normalizeScriptPolicyPath, parseAgentFile, parseAgentMarkdown, readSkillResource, renderAgentPrompt, resolveAgentIdentity, resolveMemoryConfig, resolveSkillDirs, resolveStateConfig, slugifyStorageComponent };
|
package/dist/index.js
CHANGED
|
@@ -330,8 +330,8 @@ var resolveStateConfig = (config) => {
|
|
|
330
330
|
if (config?.storage) {
|
|
331
331
|
return {
|
|
332
332
|
provider: config.storage.provider,
|
|
333
|
-
|
|
334
|
-
|
|
333
|
+
urlEnv: config.storage.urlEnv,
|
|
334
|
+
tokenEnv: config.storage.tokenEnv,
|
|
335
335
|
table: config.storage.table,
|
|
336
336
|
region: config.storage.region,
|
|
337
337
|
ttl: resolveTtl(config.storage.ttl, "conversations")
|
|
@@ -344,8 +344,8 @@ var resolveMemoryConfig = (config) => {
|
|
|
344
344
|
return {
|
|
345
345
|
enabled: config.storage.memory?.enabled ?? config.memory?.enabled,
|
|
346
346
|
provider: config.storage.provider,
|
|
347
|
-
|
|
348
|
-
|
|
347
|
+
urlEnv: config.storage.urlEnv,
|
|
348
|
+
tokenEnv: config.storage.tokenEnv,
|
|
349
349
|
table: config.storage.table,
|
|
350
350
|
region: config.storage.region,
|
|
351
351
|
ttl: resolveTtl(config.storage.ttl, "memory"),
|
|
@@ -1121,8 +1121,10 @@ var createMemoryStore = (agentId, config, options) => {
|
|
|
1121
1121
|
return new InMemoryMemoryStore(ttl);
|
|
1122
1122
|
}
|
|
1123
1123
|
if (provider === "upstash") {
|
|
1124
|
-
const
|
|
1125
|
-
const
|
|
1124
|
+
const urlEnv = config?.urlEnv ?? (process.env.UPSTASH_REDIS_REST_URL ? "UPSTASH_REDIS_REST_URL" : "KV_REST_API_URL");
|
|
1125
|
+
const tokenEnv = config?.tokenEnv ?? (process.env.UPSTASH_REDIS_REST_TOKEN ? "UPSTASH_REDIS_REST_TOKEN" : "KV_REST_API_TOKEN");
|
|
1126
|
+
const url = process.env[urlEnv] ?? "";
|
|
1127
|
+
const token = process.env[tokenEnv] ?? "";
|
|
1126
1128
|
if (url && token) {
|
|
1127
1129
|
return new UpstashMemoryStore({
|
|
1128
1130
|
baseUrl: url,
|
|
@@ -1134,7 +1136,8 @@ var createMemoryStore = (agentId, config, options) => {
|
|
|
1134
1136
|
return new InMemoryMemoryStore(ttl);
|
|
1135
1137
|
}
|
|
1136
1138
|
if (provider === "redis") {
|
|
1137
|
-
const
|
|
1139
|
+
const urlEnv = config?.urlEnv ?? "REDIS_URL";
|
|
1140
|
+
const url = process.env[urlEnv] ?? "";
|
|
1138
1141
|
if (url) {
|
|
1139
1142
|
return new RedisMemoryStore({
|
|
1140
1143
|
url,
|
|
@@ -1763,16 +1766,18 @@ var getModelContextWindow = (modelName) => {
|
|
|
1763
1766
|
}
|
|
1764
1767
|
return best ? MODEL_CONTEXT_WINDOWS[best] : DEFAULT_CONTEXT_WINDOW;
|
|
1765
1768
|
};
|
|
1766
|
-
var createModelProvider = (provider) => {
|
|
1769
|
+
var createModelProvider = (provider, config) => {
|
|
1767
1770
|
const normalized = (provider ?? "anthropic").toLowerCase();
|
|
1768
1771
|
if (normalized === "openai") {
|
|
1772
|
+
const apiKeyEnv2 = config?.openai?.apiKeyEnv ?? "OPENAI_API_KEY";
|
|
1769
1773
|
const openai = createOpenAI({
|
|
1770
|
-
apiKey: process.env
|
|
1774
|
+
apiKey: process.env[apiKeyEnv2]
|
|
1771
1775
|
});
|
|
1772
1776
|
return (modelName) => openai(modelName);
|
|
1773
1777
|
}
|
|
1778
|
+
const apiKeyEnv = config?.anthropic?.apiKeyEnv ?? "ANTHROPIC_API_KEY";
|
|
1774
1779
|
const anthropic = createAnthropic({
|
|
1775
|
-
apiKey: process.env
|
|
1780
|
+
apiKey: process.env[apiKeyEnv]
|
|
1776
1781
|
});
|
|
1777
1782
|
return (modelName) => anthropic(modelName);
|
|
1778
1783
|
};
|
|
@@ -2812,18 +2817,51 @@ When configuring Latitude telemetry, use **exactly** these field names:
|
|
|
2812
2817
|
telemetry: {
|
|
2813
2818
|
enabled: true,
|
|
2814
2819
|
latitude: {
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
path: "your/prompt-path",
|
|
2820
|
+
apiKeyEnv: "LATITUDE_API_KEY", // env var name (default)
|
|
2821
|
+
projectIdEnv: "LATITUDE_PROJECT_ID", // env var name (default)
|
|
2822
|
+
path: "your/prompt-path", // optional, defaults to agent name
|
|
2818
2823
|
},
|
|
2819
2824
|
},
|
|
2820
2825
|
\`\`\`
|
|
2821
2826
|
|
|
2822
|
-
-
|
|
2823
|
-
-
|
|
2827
|
+
- \`apiKeyEnv\` specifies the environment variable name for the Latitude API key (defaults to \`"LATITUDE_API_KEY"\`).
|
|
2828
|
+
- \`projectIdEnv\` specifies the environment variable name for the project ID (defaults to \`"LATITUDE_PROJECT_ID"\`).
|
|
2829
|
+
- With defaults, you only need \`telemetry: { latitude: {} }\` if the env vars are already named \`LATITUDE_API_KEY\` and \`LATITUDE_PROJECT_ID\`.
|
|
2824
2830
|
- \`path\` must only contain letters, numbers, hyphens, underscores, dots, and slashes.
|
|
2825
2831
|
- For a generic OTLP endpoint instead: \`telemetry: { otlp: process.env.OTEL_EXPORTER_OTLP_ENDPOINT }\`.
|
|
2826
|
-
|
|
2832
|
+
|
|
2833
|
+
## Credential Configuration Pattern
|
|
2834
|
+
|
|
2835
|
+
All credentials in \`poncho.config.js\` use the **env var name** pattern (\`*Env\` fields). Config specifies which environment variable to read \u2014 never the secret itself. Sensible defaults mean zero config when using conventional env var names.
|
|
2836
|
+
|
|
2837
|
+
\`\`\`javascript
|
|
2838
|
+
// poncho.config.js \u2014 credentials use *Env fields with defaults
|
|
2839
|
+
export default {
|
|
2840
|
+
// Model provider API keys (optional, defaults shown)
|
|
2841
|
+
providers: {
|
|
2842
|
+
anthropic: { apiKeyEnv: "ANTHROPIC_API_KEY" },
|
|
2843
|
+
openai: { apiKeyEnv: "OPENAI_API_KEY" },
|
|
2844
|
+
},
|
|
2845
|
+
auth: {
|
|
2846
|
+
required: true,
|
|
2847
|
+
tokenEnv: "PONCHO_AUTH_TOKEN", // default
|
|
2848
|
+
},
|
|
2849
|
+
storage: {
|
|
2850
|
+
provider: "upstash",
|
|
2851
|
+
urlEnv: "UPSTASH_REDIS_REST_URL", // default (falls back to KV_REST_API_URL)
|
|
2852
|
+
tokenEnv: "UPSTASH_REDIS_REST_TOKEN", // default (falls back to KV_REST_API_TOKEN)
|
|
2853
|
+
},
|
|
2854
|
+
telemetry: {
|
|
2855
|
+
latitude: {
|
|
2856
|
+
apiKeyEnv: "LATITUDE_API_KEY", // default
|
|
2857
|
+
projectIdEnv: "LATITUDE_PROJECT_ID", // default
|
|
2858
|
+
},
|
|
2859
|
+
},
|
|
2860
|
+
messaging: [{ platform: "slack" }], // reads SLACK_BOT_TOKEN, SLACK_SIGNING_SECRET by default
|
|
2861
|
+
}
|
|
2862
|
+
\`\`\`
|
|
2863
|
+
|
|
2864
|
+
Since all fields have defaults, you only need to specify \`*Env\` when your env var name differs from the convention.
|
|
2827
2865
|
|
|
2828
2866
|
## When users ask about customization:
|
|
2829
2867
|
|
|
@@ -2838,6 +2876,7 @@ telemetry: {
|
|
|
2838
2876
|
- To scope tools to a skill: keep server config in \`poncho.config.js\`, add desired \`allowed-tools\`/ \`approval-required\` patterns in that skill's \`SKILL.md\`, and remove global \`AGENT.md\` patterns if you do not want global availability.
|
|
2839
2877
|
- Do not invent unsupported top-level config keys (for example \`model\` in \`poncho.config.js\`). Keep existing config structure unless README/spec explicitly says otherwise.
|
|
2840
2878
|
- Keep \`poncho.config.js\` valid JavaScript and preserve existing imports/types/comments. If there is a JSDoc type import, do not rewrite it to a different package name.
|
|
2879
|
+
- Credentials always use \`*Env\` fields (env var names), never raw \`process.env.*\` values. For example, use \`apiKeyEnv: "MY_KEY"\` not \`apiKey: process.env.MY_KEY\`.
|
|
2841
2880
|
- Preferred MCP config shape in \`poncho.config.js\`:
|
|
2842
2881
|
\`mcp: [{ name: "linear", url: "https://mcp.linear.app/mcp", auth: { type: "bearer", tokenEnv: "LINEAR_TOKEN" } }]\`
|
|
2843
2882
|
- If shell/CLI access exists, you can use \`poncho mcp add --url ... --name ... --auth-bearer-env ...\`, then \`poncho mcp tools list <server>\` and \`poncho mcp tools select <server>\`.
|
|
@@ -3157,7 +3196,7 @@ var AgentHarness = class {
|
|
|
3157
3196
|
const provider = this.parsedAgent.frontmatter.model?.provider ?? "anthropic";
|
|
3158
3197
|
const memoryConfig = resolveMemoryConfig(config);
|
|
3159
3198
|
if (!this.modelProviderInjected) {
|
|
3160
|
-
this.modelProvider = createModelProvider(provider);
|
|
3199
|
+
this.modelProvider = createModelProvider(provider, config?.providers);
|
|
3161
3200
|
}
|
|
3162
3201
|
const bridge = new LocalMcpBridge(config);
|
|
3163
3202
|
this.mcpBridge = bridge;
|
|
@@ -3184,10 +3223,12 @@ var AgentHarness = class {
|
|
|
3184
3223
|
await bridge.discoverTools();
|
|
3185
3224
|
await this.refreshMcpTools("initialize");
|
|
3186
3225
|
const telemetryEnabled = config?.telemetry?.enabled !== false;
|
|
3187
|
-
const latitudeApiKey = config?.telemetry?.latitude?.apiKey;
|
|
3188
|
-
const rawProjectId = config?.telemetry?.latitude?.projectId;
|
|
3189
|
-
const latitudeProjectId = typeof rawProjectId === "string" ? parseInt(rawProjectId, 10) : rawProjectId;
|
|
3190
3226
|
const latitudeBlock = config?.telemetry?.latitude;
|
|
3227
|
+
const latApiKeyEnv = latitudeBlock?.apiKeyEnv ?? "LATITUDE_API_KEY";
|
|
3228
|
+
const latProjectIdEnv = latitudeBlock?.projectIdEnv ?? "LATITUDE_PROJECT_ID";
|
|
3229
|
+
const latitudeApiKey = process.env[latApiKeyEnv];
|
|
3230
|
+
const rawProjectId = process.env[latProjectIdEnv];
|
|
3231
|
+
const latitudeProjectId = rawProjectId ? parseInt(rawProjectId, 10) : void 0;
|
|
3191
3232
|
if (telemetryEnabled && latitudeApiKey && latitudeProjectId) {
|
|
3192
3233
|
diag.setLogger(
|
|
3193
3234
|
{
|
|
@@ -3209,14 +3250,10 @@ var AgentHarness = class {
|
|
|
3209
3250
|
this.latitudeTelemetry = new LatitudeTelemetry(latitudeApiKey, { disableBatch: true });
|
|
3210
3251
|
} else if (telemetryEnabled && latitudeBlock && (!latitudeApiKey || !latitudeProjectId)) {
|
|
3211
3252
|
const missing = [];
|
|
3212
|
-
if (!latitudeApiKey) missing.push(
|
|
3213
|
-
if (!latitudeProjectId) missing.push(
|
|
3214
|
-
const unknownKeys = Object.keys(latitudeBlock).filter(
|
|
3215
|
-
(k) => !["apiKey", "projectId", "path", "documentPath"].includes(k)
|
|
3216
|
-
);
|
|
3217
|
-
const hint = unknownKeys.length > 0 ? ` (found unknown key${unknownKeys.length > 1 ? "s" : ""}: ${unknownKeys.join(", ")} \u2013 did you mean "apiKey"?)` : "";
|
|
3253
|
+
if (!latitudeApiKey) missing.push(`${latApiKeyEnv} env var`);
|
|
3254
|
+
if (!latitudeProjectId) missing.push(`${latProjectIdEnv} env var`);
|
|
3218
3255
|
console.warn(
|
|
3219
|
-
`[poncho][telemetry] Latitude telemetry is configured but missing: ${missing.join(", ")}
|
|
3256
|
+
`[poncho][telemetry] Latitude telemetry is configured but missing: ${missing.join(", ")}. Traces will NOT be sent.`
|
|
3220
3257
|
);
|
|
3221
3258
|
}
|
|
3222
3259
|
}
|
|
@@ -3242,8 +3279,8 @@ var AgentHarness = class {
|
|
|
3242
3279
|
const config = this.loadedConfig;
|
|
3243
3280
|
const telemetry = this.latitudeTelemetry;
|
|
3244
3281
|
if (telemetry) {
|
|
3245
|
-
const
|
|
3246
|
-
const projectId =
|
|
3282
|
+
const latProjectIdEnv2 = config?.telemetry?.latitude?.projectIdEnv ?? "LATITUDE_PROJECT_ID";
|
|
3283
|
+
const projectId = parseInt(process.env[latProjectIdEnv2] ?? "", 10);
|
|
3247
3284
|
const rawPath = config?.telemetry?.latitude?.path ?? this.parsedAgent?.frontmatter.name ?? "agent";
|
|
3248
3285
|
const path = rawPath.replace(/[^\w\-./]/g, "-").replace(/-+/g, "-").replace(/^-+|-+$/g, "") || "agent";
|
|
3249
3286
|
const conversationUuid = input.conversationId ?? (typeof input.parameters?.__activeConversationId === "string" ? input.parameters.__activeConversationId : void 0);
|
|
@@ -3641,7 +3678,6 @@ ${textContent}` };
|
|
|
3641
3678
|
const modelInstance = this.modelProvider(modelName);
|
|
3642
3679
|
const cachedMessages = addPromptCacheBreakpoints(coreMessages, modelInstance);
|
|
3643
3680
|
const telemetryEnabled = this.loadedConfig?.telemetry?.enabled !== false;
|
|
3644
|
-
const latitudeApiKey = this.loadedConfig?.telemetry?.latitude?.apiKey;
|
|
3645
3681
|
const result = await streamText({
|
|
3646
3682
|
model: modelInstance,
|
|
3647
3683
|
system: integrityPrompt,
|
|
@@ -3651,7 +3687,7 @@ ${textContent}` };
|
|
|
3651
3687
|
abortSignal: input.abortSignal,
|
|
3652
3688
|
...typeof maxTokens === "number" ? { maxTokens } : {},
|
|
3653
3689
|
experimental_telemetry: {
|
|
3654
|
-
isEnabled: telemetryEnabled && !!
|
|
3690
|
+
isEnabled: telemetryEnabled && !!this.latitudeTelemetry
|
|
3655
3691
|
}
|
|
3656
3692
|
});
|
|
3657
3693
|
let fullText = "";
|
|
@@ -4114,9 +4150,11 @@ var LatitudeCapture = class {
|
|
|
4114
4150
|
projectId;
|
|
4115
4151
|
path;
|
|
4116
4152
|
constructor(config) {
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
const
|
|
4153
|
+
const apiKeyEnv = config?.apiKeyEnv ?? "LATITUDE_API_KEY";
|
|
4154
|
+
this.apiKey = process.env[apiKeyEnv];
|
|
4155
|
+
const projectIdEnv = config?.projectIdEnv ?? "LATITUDE_PROJECT_ID";
|
|
4156
|
+
const rawProjectId = process.env[projectIdEnv];
|
|
4157
|
+
const projectIdNumber = rawProjectId ? Number.parseInt(rawProjectId, 10) : Number.NaN;
|
|
4120
4158
|
this.projectId = Number.isFinite(projectIdNumber) ? projectIdNumber : void 0;
|
|
4121
4159
|
const rawPath = config?.path ?? process.env.LATITUDE_PATH ?? process.env.LATITUDE_DOCUMENT_PATH ?? config?.defaultPath;
|
|
4122
4160
|
this.path = rawPath;
|
|
@@ -5024,15 +5062,18 @@ var createStateStore = (config, options) => {
|
|
|
5024
5062
|
return new InMemoryStateStore(ttl);
|
|
5025
5063
|
}
|
|
5026
5064
|
if (provider === "upstash") {
|
|
5027
|
-
const
|
|
5028
|
-
const
|
|
5065
|
+
const urlEnv = config?.urlEnv ?? (process.env.UPSTASH_REDIS_REST_URL ? "UPSTASH_REDIS_REST_URL" : "KV_REST_API_URL");
|
|
5066
|
+
const tokenEnv = config?.tokenEnv ?? (process.env.UPSTASH_REDIS_REST_TOKEN ? "UPSTASH_REDIS_REST_TOKEN" : "KV_REST_API_TOKEN");
|
|
5067
|
+
const url = process.env[urlEnv] ?? "";
|
|
5068
|
+
const token = process.env[tokenEnv] ?? "";
|
|
5029
5069
|
if (url && token) {
|
|
5030
5070
|
return new UpstashStateStore(url, token, ttl);
|
|
5031
5071
|
}
|
|
5032
5072
|
return new InMemoryStateStore(ttl);
|
|
5033
5073
|
}
|
|
5034
5074
|
if (provider === "redis") {
|
|
5035
|
-
const
|
|
5075
|
+
const urlEnv = config?.urlEnv ?? "REDIS_URL";
|
|
5076
|
+
const url = process.env[urlEnv] ?? "";
|
|
5036
5077
|
if (url) {
|
|
5037
5078
|
return new RedisLikeStateStore(url, ttl);
|
|
5038
5079
|
}
|
|
@@ -5058,15 +5099,18 @@ var createConversationStore = (config, options) => {
|
|
|
5058
5099
|
return new InMemoryConversationStore(ttl);
|
|
5059
5100
|
}
|
|
5060
5101
|
if (provider === "upstash") {
|
|
5061
|
-
const
|
|
5062
|
-
const
|
|
5102
|
+
const urlEnv = config?.urlEnv ?? (process.env.UPSTASH_REDIS_REST_URL ? "UPSTASH_REDIS_REST_URL" : "KV_REST_API_URL");
|
|
5103
|
+
const tokenEnv = config?.tokenEnv ?? (process.env.UPSTASH_REDIS_REST_TOKEN ? "UPSTASH_REDIS_REST_TOKEN" : "KV_REST_API_TOKEN");
|
|
5104
|
+
const url = process.env[urlEnv] ?? "";
|
|
5105
|
+
const token = process.env[tokenEnv] ?? "";
|
|
5063
5106
|
if (url && token) {
|
|
5064
5107
|
return new UpstashConversationStore(url, token, workingDir, ttl, options?.agentId);
|
|
5065
5108
|
}
|
|
5066
5109
|
return new InMemoryConversationStore(ttl);
|
|
5067
5110
|
}
|
|
5068
5111
|
if (provider === "redis") {
|
|
5069
|
-
const
|
|
5112
|
+
const urlEnv = config?.urlEnv ?? "REDIS_URL";
|
|
5113
|
+
const url = process.env[urlEnv] ?? "";
|
|
5070
5114
|
if (url) {
|
|
5071
5115
|
return new RedisLikeConversationStore(url, workingDir, ttl, options?.agentId);
|
|
5072
5116
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@poncho-ai/harness",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.2",
|
|
4
4
|
"description": "Agent execution runtime - conversation loop, tool dispatch, streaming",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"redis": "^5.10.0",
|
|
32
32
|
"yaml": "^2.4.0",
|
|
33
33
|
"zod": "^3.22.0",
|
|
34
|
-
"@poncho-ai/sdk": "1.0.
|
|
34
|
+
"@poncho-ai/sdk": "1.0.3"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@types/mustache": "^4.2.6",
|
package/src/config.ts
CHANGED
|
@@ -7,8 +7,8 @@ import type { StateConfig } from "./state.js";
|
|
|
7
7
|
|
|
8
8
|
export interface StorageConfig {
|
|
9
9
|
provider?: "local" | "memory" | "redis" | "upstash" | "dynamodb";
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
urlEnv?: string;
|
|
11
|
+
tokenEnv?: string;
|
|
12
12
|
table?: string;
|
|
13
13
|
region?: string;
|
|
14
14
|
ttl?:
|
|
@@ -76,6 +76,7 @@ export interface PonchoConfig extends McpConfig {
|
|
|
76
76
|
required?: boolean;
|
|
77
77
|
type?: "bearer" | "header" | "custom";
|
|
78
78
|
headerName?: string;
|
|
79
|
+
tokenEnv?: string;
|
|
79
80
|
validate?: (token: string, req?: unknown) => Promise<boolean> | boolean;
|
|
80
81
|
};
|
|
81
82
|
state?: {
|
|
@@ -85,12 +86,16 @@ export interface PonchoConfig extends McpConfig {
|
|
|
85
86
|
};
|
|
86
87
|
memory?: MemoryConfig;
|
|
87
88
|
storage?: StorageConfig;
|
|
89
|
+
providers?: {
|
|
90
|
+
openai?: { apiKeyEnv?: string };
|
|
91
|
+
anthropic?: { apiKeyEnv?: string };
|
|
92
|
+
};
|
|
88
93
|
telemetry?: {
|
|
89
94
|
enabled?: boolean;
|
|
90
95
|
otlp?: string;
|
|
91
96
|
latitude?: {
|
|
92
|
-
|
|
93
|
-
|
|
97
|
+
apiKeyEnv?: string;
|
|
98
|
+
projectIdEnv?: string;
|
|
94
99
|
path?: string;
|
|
95
100
|
documentPath?: string;
|
|
96
101
|
};
|
|
@@ -130,8 +135,8 @@ export const resolveStateConfig = (
|
|
|
130
135
|
if (config?.storage) {
|
|
131
136
|
return {
|
|
132
137
|
provider: config.storage.provider,
|
|
133
|
-
|
|
134
|
-
|
|
138
|
+
urlEnv: config.storage.urlEnv,
|
|
139
|
+
tokenEnv: config.storage.tokenEnv,
|
|
135
140
|
table: config.storage.table,
|
|
136
141
|
region: config.storage.region,
|
|
137
142
|
ttl: resolveTtl(config.storage.ttl, "conversations"),
|
|
@@ -147,8 +152,8 @@ export const resolveMemoryConfig = (
|
|
|
147
152
|
return {
|
|
148
153
|
enabled: config.storage.memory?.enabled ?? config.memory?.enabled,
|
|
149
154
|
provider: config.storage.provider,
|
|
150
|
-
|
|
151
|
-
|
|
155
|
+
urlEnv: config.storage.urlEnv,
|
|
156
|
+
tokenEnv: config.storage.tokenEnv,
|
|
152
157
|
table: config.storage.table,
|
|
153
158
|
region: config.storage.region,
|
|
154
159
|
ttl: resolveTtl(config.storage.ttl, "memory"),
|
package/src/harness.ts
CHANGED
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
type MemoryStore,
|
|
23
23
|
} from "./memory.js";
|
|
24
24
|
import { LocalMcpBridge } from "./mcp.js";
|
|
25
|
-
import { createModelProvider, getModelContextWindow, type ModelProviderFactory } from "./model-factory.js";
|
|
25
|
+
import { createModelProvider, getModelContextWindow, type ModelProviderFactory, type ProviderConfig } from "./model-factory.js";
|
|
26
26
|
import { buildSkillContextWindow, loadSkillMetadata } from "./skill-context.js";
|
|
27
27
|
import { streamText, type ModelMessage } from "ai";
|
|
28
28
|
import { addPromptCacheBreakpoints } from "./prompt-cache.js";
|
|
@@ -367,18 +367,51 @@ When configuring Latitude telemetry, use **exactly** these field names:
|
|
|
367
367
|
telemetry: {
|
|
368
368
|
enabled: true,
|
|
369
369
|
latitude: {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
path: "your/prompt-path",
|
|
370
|
+
apiKeyEnv: "LATITUDE_API_KEY", // env var name (default)
|
|
371
|
+
projectIdEnv: "LATITUDE_PROJECT_ID", // env var name (default)
|
|
372
|
+
path: "your/prompt-path", // optional, defaults to agent name
|
|
373
373
|
},
|
|
374
374
|
},
|
|
375
375
|
\`\`\`
|
|
376
376
|
|
|
377
|
-
-
|
|
378
|
-
-
|
|
377
|
+
- \`apiKeyEnv\` specifies the environment variable name for the Latitude API key (defaults to \`"LATITUDE_API_KEY"\`).
|
|
378
|
+
- \`projectIdEnv\` specifies the environment variable name for the project ID (defaults to \`"LATITUDE_PROJECT_ID"\`).
|
|
379
|
+
- With defaults, you only need \`telemetry: { latitude: {} }\` if the env vars are already named \`LATITUDE_API_KEY\` and \`LATITUDE_PROJECT_ID\`.
|
|
379
380
|
- \`path\` must only contain letters, numbers, hyphens, underscores, dots, and slashes.
|
|
380
381
|
- For a generic OTLP endpoint instead: \`telemetry: { otlp: process.env.OTEL_EXPORTER_OTLP_ENDPOINT }\`.
|
|
381
|
-
|
|
382
|
+
|
|
383
|
+
## Credential Configuration Pattern
|
|
384
|
+
|
|
385
|
+
All credentials in \`poncho.config.js\` use the **env var name** pattern (\`*Env\` fields). Config specifies which environment variable to read — never the secret itself. Sensible defaults mean zero config when using conventional env var names.
|
|
386
|
+
|
|
387
|
+
\`\`\`javascript
|
|
388
|
+
// poncho.config.js — credentials use *Env fields with defaults
|
|
389
|
+
export default {
|
|
390
|
+
// Model provider API keys (optional, defaults shown)
|
|
391
|
+
providers: {
|
|
392
|
+
anthropic: { apiKeyEnv: "ANTHROPIC_API_KEY" },
|
|
393
|
+
openai: { apiKeyEnv: "OPENAI_API_KEY" },
|
|
394
|
+
},
|
|
395
|
+
auth: {
|
|
396
|
+
required: true,
|
|
397
|
+
tokenEnv: "PONCHO_AUTH_TOKEN", // default
|
|
398
|
+
},
|
|
399
|
+
storage: {
|
|
400
|
+
provider: "upstash",
|
|
401
|
+
urlEnv: "UPSTASH_REDIS_REST_URL", // default (falls back to KV_REST_API_URL)
|
|
402
|
+
tokenEnv: "UPSTASH_REDIS_REST_TOKEN", // default (falls back to KV_REST_API_TOKEN)
|
|
403
|
+
},
|
|
404
|
+
telemetry: {
|
|
405
|
+
latitude: {
|
|
406
|
+
apiKeyEnv: "LATITUDE_API_KEY", // default
|
|
407
|
+
projectIdEnv: "LATITUDE_PROJECT_ID", // default
|
|
408
|
+
},
|
|
409
|
+
},
|
|
410
|
+
messaging: [{ platform: "slack" }], // reads SLACK_BOT_TOKEN, SLACK_SIGNING_SECRET by default
|
|
411
|
+
}
|
|
412
|
+
\`\`\`
|
|
413
|
+
|
|
414
|
+
Since all fields have defaults, you only need to specify \`*Env\` when your env var name differs from the convention.
|
|
382
415
|
|
|
383
416
|
## When users ask about customization:
|
|
384
417
|
|
|
@@ -393,6 +426,7 @@ telemetry: {
|
|
|
393
426
|
- To scope tools to a skill: keep server config in \`poncho.config.js\`, add desired \`allowed-tools\`/ \`approval-required\` patterns in that skill's \`SKILL.md\`, and remove global \`AGENT.md\` patterns if you do not want global availability.
|
|
394
427
|
- Do not invent unsupported top-level config keys (for example \`model\` in \`poncho.config.js\`). Keep existing config structure unless README/spec explicitly says otherwise.
|
|
395
428
|
- Keep \`poncho.config.js\` valid JavaScript and preserve existing imports/types/comments. If there is a JSDoc type import, do not rewrite it to a different package name.
|
|
429
|
+
- Credentials always use \`*Env\` fields (env var names), never raw \`process.env.*\` values. For example, use \`apiKeyEnv: "MY_KEY"\` not \`apiKey: process.env.MY_KEY\`.
|
|
396
430
|
- Preferred MCP config shape in \`poncho.config.js\`:
|
|
397
431
|
\`mcp: [{ name: "linear", url: "https://mcp.linear.app/mcp", auth: { type: "bearer", tokenEnv: "LINEAR_TOKEN" } }]\`
|
|
398
432
|
- If shell/CLI access exists, you can use \`poncho mcp add --url ... --name ... --auth-bearer-env ...\`, then \`poncho mcp tools list <server>\` and \`poncho mcp tools select <server>\`.
|
|
@@ -758,10 +792,8 @@ export class AgentHarness {
|
|
|
758
792
|
this.registerConfiguredBuiltInTools(config);
|
|
759
793
|
const provider = this.parsedAgent.frontmatter.model?.provider ?? "anthropic";
|
|
760
794
|
const memoryConfig = resolveMemoryConfig(config);
|
|
761
|
-
// Only create modelProvider if one wasn't injected (for production use)
|
|
762
|
-
// Tests can inject a mock modelProvider via constructor options
|
|
763
795
|
if (!this.modelProviderInjected) {
|
|
764
|
-
this.modelProvider = createModelProvider(provider);
|
|
796
|
+
this.modelProvider = createModelProvider(provider, config?.providers);
|
|
765
797
|
}
|
|
766
798
|
const bridge = new LocalMcpBridge(config);
|
|
767
799
|
this.mcpBridge = bridge;
|
|
@@ -793,14 +825,13 @@ export class AgentHarness {
|
|
|
793
825
|
// Creating a new LatitudeTelemetry per run would break on the second call
|
|
794
826
|
// because @opentelemetry/api silently ignores repeated global registrations.
|
|
795
827
|
const telemetryEnabled = config?.telemetry?.enabled !== false;
|
|
796
|
-
const latitudeApiKey = config?.telemetry?.latitude?.apiKey;
|
|
797
|
-
const rawProjectId = config?.telemetry?.latitude?.projectId;
|
|
798
|
-
const latitudeProjectId = typeof rawProjectId === 'string' ? parseInt(rawProjectId, 10) : rawProjectId;
|
|
799
828
|
const latitudeBlock = config?.telemetry?.latitude;
|
|
829
|
+
const latApiKeyEnv = latitudeBlock?.apiKeyEnv ?? "LATITUDE_API_KEY";
|
|
830
|
+
const latProjectIdEnv = latitudeBlock?.projectIdEnv ?? "LATITUDE_PROJECT_ID";
|
|
831
|
+
const latitudeApiKey = process.env[latApiKeyEnv];
|
|
832
|
+
const rawProjectId = process.env[latProjectIdEnv];
|
|
833
|
+
const latitudeProjectId = rawProjectId ? parseInt(rawProjectId, 10) : undefined;
|
|
800
834
|
if (telemetryEnabled && latitudeApiKey && latitudeProjectId) {
|
|
801
|
-
// Surface genuine OTLP export failures. Suppress "duplicate registration"
|
|
802
|
-
// errors that fire when the dev server re-initializes the harness — the
|
|
803
|
-
// first registration persists and telemetry keeps working.
|
|
804
835
|
diag.setLogger(
|
|
805
836
|
{
|
|
806
837
|
error: (msg, ...args) => {
|
|
@@ -817,16 +848,10 @@ export class AgentHarness {
|
|
|
817
848
|
this.latitudeTelemetry = new LatitudeTelemetry(latitudeApiKey, { disableBatch: true });
|
|
818
849
|
} else if (telemetryEnabled && latitudeBlock && (!latitudeApiKey || !latitudeProjectId)) {
|
|
819
850
|
const missing: string[] = [];
|
|
820
|
-
if (!latitudeApiKey) missing.push(
|
|
821
|
-
if (!latitudeProjectId) missing.push(
|
|
822
|
-
const unknownKeys = Object.keys(latitudeBlock).filter(
|
|
823
|
-
(k) => !["apiKey", "projectId", "path", "documentPath"].includes(k),
|
|
824
|
-
);
|
|
825
|
-
const hint = unknownKeys.length > 0
|
|
826
|
-
? ` (found unknown key${unknownKeys.length > 1 ? "s" : ""}: ${unknownKeys.join(", ")} – did you mean "apiKey"?)`
|
|
827
|
-
: "";
|
|
851
|
+
if (!latitudeApiKey) missing.push(`${latApiKeyEnv} env var`);
|
|
852
|
+
if (!latitudeProjectId) missing.push(`${latProjectIdEnv} env var`);
|
|
828
853
|
console.warn(
|
|
829
|
-
`[poncho][telemetry] Latitude telemetry is configured but missing: ${missing.join(", ")}
|
|
854
|
+
`[poncho][telemetry] Latitude telemetry is configured but missing: ${missing.join(", ")}. Traces will NOT be sent.`,
|
|
830
855
|
);
|
|
831
856
|
}
|
|
832
857
|
}
|
|
@@ -858,8 +883,8 @@ export class AgentHarness {
|
|
|
858
883
|
const telemetry = this.latitudeTelemetry;
|
|
859
884
|
|
|
860
885
|
if (telemetry) {
|
|
861
|
-
const
|
|
862
|
-
const projectId = (
|
|
886
|
+
const latProjectIdEnv2 = config?.telemetry?.latitude?.projectIdEnv ?? "LATITUDE_PROJECT_ID";
|
|
887
|
+
const projectId = parseInt(process.env[latProjectIdEnv2] ?? "", 10) as number;
|
|
863
888
|
const rawPath = config?.telemetry?.latitude?.path ?? this.parsedAgent?.frontmatter.name ?? 'agent';
|
|
864
889
|
// Sanitize path for Latitude's DOCUMENT_PATH_REGEXP: /^([\w-]+\/)*([\w-.])+$/
|
|
865
890
|
const path = rawPath.replace(/[^\w\-./]/g, '-').replace(/-+/g, '-').replace(/^-+|-+$/g, '') || 'agent';
|
|
@@ -1340,9 +1365,7 @@ ${boundedMainMemory.trim()}`
|
|
|
1340
1365
|
const modelInstance = this.modelProvider(modelName);
|
|
1341
1366
|
const cachedMessages = addPromptCacheBreakpoints(coreMessages, modelInstance);
|
|
1342
1367
|
|
|
1343
|
-
// Stream response using Vercel AI SDK with telemetry enabled
|
|
1344
1368
|
const telemetryEnabled = this.loadedConfig?.telemetry?.enabled !== false;
|
|
1345
|
-
const latitudeApiKey = this.loadedConfig?.telemetry?.latitude?.apiKey;
|
|
1346
1369
|
|
|
1347
1370
|
const result = await streamText({
|
|
1348
1371
|
model: modelInstance,
|
|
@@ -1353,7 +1376,7 @@ ${boundedMainMemory.trim()}`
|
|
|
1353
1376
|
abortSignal: input.abortSignal,
|
|
1354
1377
|
...(typeof maxTokens === "number" ? { maxTokens } : {}),
|
|
1355
1378
|
experimental_telemetry: {
|
|
1356
|
-
isEnabled: telemetryEnabled && !!
|
|
1379
|
+
isEnabled: telemetryEnabled && !!this.latitudeTelemetry,
|
|
1357
1380
|
},
|
|
1358
1381
|
});
|
|
1359
1382
|
// Stream text chunks — enforce overall run timeout per chunk.
|
package/src/latitude-capture.ts
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
export interface LatitudeCaptureConfig {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
apiKeyEnv?: string;
|
|
14
|
+
projectIdEnv?: string;
|
|
15
15
|
path?: string;
|
|
16
16
|
defaultPath?: string;
|
|
17
17
|
}
|
|
@@ -26,15 +26,14 @@ export class LatitudeCapture {
|
|
|
26
26
|
private readonly path?: string;
|
|
27
27
|
|
|
28
28
|
constructor(config?: LatitudeCaptureConfig) {
|
|
29
|
-
|
|
29
|
+
const apiKeyEnv = config?.apiKeyEnv ?? "LATITUDE_API_KEY";
|
|
30
|
+
this.apiKey = process.env[apiKeyEnv];
|
|
30
31
|
|
|
31
|
-
const
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
? Number.parseInt(rawProjectId, 10)
|
|
37
|
-
: Number.NaN;
|
|
32
|
+
const projectIdEnv = config?.projectIdEnv ?? "LATITUDE_PROJECT_ID";
|
|
33
|
+
const rawProjectId = process.env[projectIdEnv];
|
|
34
|
+
const projectIdNumber = rawProjectId
|
|
35
|
+
? Number.parseInt(rawProjectId, 10)
|
|
36
|
+
: Number.NaN;
|
|
38
37
|
this.projectId = Number.isFinite(projectIdNumber) ? projectIdNumber : undefined;
|
|
39
38
|
|
|
40
39
|
const rawPath =
|
package/src/memory.ts
CHANGED
|
@@ -17,8 +17,8 @@ export interface MainMemory {
|
|
|
17
17
|
export interface MemoryConfig {
|
|
18
18
|
enabled?: boolean;
|
|
19
19
|
provider?: StateProviderName;
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
urlEnv?: string;
|
|
21
|
+
tokenEnv?: string;
|
|
22
22
|
table?: string;
|
|
23
23
|
region?: string;
|
|
24
24
|
ttl?: number;
|
|
@@ -495,16 +495,10 @@ export const createMemoryStore = (
|
|
|
495
495
|
return new InMemoryMemoryStore(ttl);
|
|
496
496
|
}
|
|
497
497
|
if (provider === "upstash") {
|
|
498
|
-
const
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
"";
|
|
503
|
-
const token =
|
|
504
|
-
config?.token ??
|
|
505
|
-
process.env.UPSTASH_REDIS_REST_TOKEN ??
|
|
506
|
-
process.env.KV_REST_API_TOKEN ??
|
|
507
|
-
"";
|
|
498
|
+
const urlEnv = config?.urlEnv ?? (process.env.UPSTASH_REDIS_REST_URL ? "UPSTASH_REDIS_REST_URL" : "KV_REST_API_URL");
|
|
499
|
+
const tokenEnv = config?.tokenEnv ?? (process.env.UPSTASH_REDIS_REST_TOKEN ? "UPSTASH_REDIS_REST_TOKEN" : "KV_REST_API_TOKEN");
|
|
500
|
+
const url = process.env[urlEnv] ?? "";
|
|
501
|
+
const token = process.env[tokenEnv] ?? "";
|
|
508
502
|
if (url && token) {
|
|
509
503
|
return new UpstashMemoryStore({
|
|
510
504
|
baseUrl: url,
|
|
@@ -516,7 +510,8 @@ export const createMemoryStore = (
|
|
|
516
510
|
return new InMemoryMemoryStore(ttl);
|
|
517
511
|
}
|
|
518
512
|
if (provider === "redis") {
|
|
519
|
-
const
|
|
513
|
+
const urlEnv = config?.urlEnv ?? "REDIS_URL";
|
|
514
|
+
const url = process.env[urlEnv] ?? "";
|
|
520
515
|
if (url) {
|
|
521
516
|
return new RedisMemoryStore({
|
|
522
517
|
url,
|
package/src/model-factory.ts
CHANGED
|
@@ -49,23 +49,30 @@ export const getModelContextWindow = (modelName: string): number => {
|
|
|
49
49
|
return best ? MODEL_CONTEXT_WINDOWS[best]! : DEFAULT_CONTEXT_WINDOW;
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
+
export interface ProviderConfig {
|
|
53
|
+
openai?: { apiKeyEnv?: string };
|
|
54
|
+
anthropic?: { apiKeyEnv?: string };
|
|
55
|
+
}
|
|
56
|
+
|
|
52
57
|
/**
|
|
53
|
-
* Creates a model provider factory for the specified AI provider
|
|
54
|
-
*
|
|
55
|
-
*
|
|
58
|
+
* Creates a model provider factory for the specified AI provider.
|
|
59
|
+
* API keys are read from environment variables; override the env var
|
|
60
|
+
* name via the `providers` config in `poncho.config.js`.
|
|
56
61
|
*/
|
|
57
|
-
export const createModelProvider = (provider?: string): ModelProviderFactory => {
|
|
62
|
+
export const createModelProvider = (provider?: string, config?: ProviderConfig): ModelProviderFactory => {
|
|
58
63
|
const normalized = (provider ?? "anthropic").toLowerCase();
|
|
59
64
|
|
|
60
65
|
if (normalized === "openai") {
|
|
66
|
+
const apiKeyEnv = config?.openai?.apiKeyEnv ?? "OPENAI_API_KEY";
|
|
61
67
|
const openai = createOpenAI({
|
|
62
|
-
apiKey: process.env
|
|
68
|
+
apiKey: process.env[apiKeyEnv],
|
|
63
69
|
});
|
|
64
70
|
return (modelName: string) => openai(modelName);
|
|
65
71
|
}
|
|
66
72
|
|
|
73
|
+
const apiKeyEnv = config?.anthropic?.apiKeyEnv ?? "ANTHROPIC_API_KEY";
|
|
67
74
|
const anthropic = createAnthropic({
|
|
68
|
-
apiKey: process.env
|
|
75
|
+
apiKey: process.env[apiKeyEnv],
|
|
69
76
|
});
|
|
70
77
|
return (modelName: string) => anthropic(modelName);
|
|
71
78
|
};
|
package/src/state.ts
CHANGED
|
@@ -61,8 +61,8 @@ export type StateProviderName =
|
|
|
61
61
|
export interface StateConfig {
|
|
62
62
|
provider?: StateProviderName;
|
|
63
63
|
ttl?: number;
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
urlEnv?: string;
|
|
65
|
+
tokenEnv?: string;
|
|
66
66
|
table?: string;
|
|
67
67
|
region?: string;
|
|
68
68
|
}
|
|
@@ -1166,15 +1166,18 @@ export const createStateStore = (
|
|
|
1166
1166
|
return new InMemoryStateStore(ttl);
|
|
1167
1167
|
}
|
|
1168
1168
|
if (provider === "upstash") {
|
|
1169
|
-
const
|
|
1170
|
-
const
|
|
1169
|
+
const urlEnv = config?.urlEnv ?? (process.env.UPSTASH_REDIS_REST_URL ? "UPSTASH_REDIS_REST_URL" : "KV_REST_API_URL");
|
|
1170
|
+
const tokenEnv = config?.tokenEnv ?? (process.env.UPSTASH_REDIS_REST_TOKEN ? "UPSTASH_REDIS_REST_TOKEN" : "KV_REST_API_TOKEN");
|
|
1171
|
+
const url = process.env[urlEnv] ?? "";
|
|
1172
|
+
const token = process.env[tokenEnv] ?? "";
|
|
1171
1173
|
if (url && token) {
|
|
1172
1174
|
return new UpstashStateStore(url, token, ttl);
|
|
1173
1175
|
}
|
|
1174
1176
|
return new InMemoryStateStore(ttl);
|
|
1175
1177
|
}
|
|
1176
1178
|
if (provider === "redis") {
|
|
1177
|
-
const
|
|
1179
|
+
const urlEnv = config?.urlEnv ?? "REDIS_URL";
|
|
1180
|
+
const url = process.env[urlEnv] ?? "";
|
|
1178
1181
|
if (url) {
|
|
1179
1182
|
return new RedisLikeStateStore(url, ttl);
|
|
1180
1183
|
}
|
|
@@ -1204,19 +1207,18 @@ export const createConversationStore = (
|
|
|
1204
1207
|
return new InMemoryConversationStore(ttl);
|
|
1205
1208
|
}
|
|
1206
1209
|
if (provider === "upstash") {
|
|
1207
|
-
const
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
const token =
|
|
1211
|
-
config?.token ??
|
|
1212
|
-
(process.env.UPSTASH_REDIS_REST_TOKEN || process.env.KV_REST_API_TOKEN || "");
|
|
1210
|
+
const urlEnv = config?.urlEnv ?? (process.env.UPSTASH_REDIS_REST_URL ? "UPSTASH_REDIS_REST_URL" : "KV_REST_API_URL");
|
|
1211
|
+
const tokenEnv = config?.tokenEnv ?? (process.env.UPSTASH_REDIS_REST_TOKEN ? "UPSTASH_REDIS_REST_TOKEN" : "KV_REST_API_TOKEN");
|
|
1212
|
+
const url = process.env[urlEnv] ?? "";
|
|
1213
|
+
const token = process.env[tokenEnv] ?? "";
|
|
1213
1214
|
if (url && token) {
|
|
1214
1215
|
return new UpstashConversationStore(url, token, workingDir, ttl, options?.agentId);
|
|
1215
1216
|
}
|
|
1216
1217
|
return new InMemoryConversationStore(ttl);
|
|
1217
1218
|
}
|
|
1218
1219
|
if (provider === "redis") {
|
|
1219
|
-
const
|
|
1220
|
+
const urlEnv = config?.urlEnv ?? "REDIS_URL";
|
|
1221
|
+
const url = process.env[urlEnv] ?? "";
|
|
1220
1222
|
if (url) {
|
|
1221
1223
|
return new RedisLikeConversationStore(url, workingDir, ttl, options?.agentId);
|
|
1222
1224
|
}
|
package/src/telemetry.ts
CHANGED
package/test/telemetry.test.ts
CHANGED
|
@@ -15,7 +15,7 @@ describe("telemetry emitter", () => {
|
|
|
15
15
|
|
|
16
16
|
const emitter = new TelemetryEmitter({
|
|
17
17
|
otlp: "https://otel.example.com/v1/logs",
|
|
18
|
-
latitude: {
|
|
18
|
+
latitude: { apiKeyEnv: "LATITUDE_API_KEY" },
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
await expect(
|
|
@@ -32,8 +32,8 @@ describe("telemetry emitter", () => {
|
|
|
32
32
|
|
|
33
33
|
const emitter = new TelemetryEmitter({
|
|
34
34
|
latitude: {
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
apiKeyEnv: "LATITUDE_API_KEY",
|
|
36
|
+
projectIdEnv: "LATITUDE_PROJECT_ID",
|
|
37
37
|
documentPath: "agents/support-agent/AGENT.md",
|
|
38
38
|
},
|
|
39
39
|
});
|