@standardagents/typesafe 0.0.0 → 0.42.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +153 -1
- package/dist/index.d.ts +103 -0
- package/dist/index.js +227 -0
- package/dist/index.js.map +1 -0
- package/package.json +45 -5
- package/index.js +0 -1
package/README.md
CHANGED
|
@@ -1,3 +1,155 @@
|
|
|
1
1
|
# @standardagents/typesafe
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
First-party TypeSafe AI decision inference for Standard Agents. Jev evaluates
|
|
4
|
+
explicit context against multiple independent questions in one request. The
|
|
5
|
+
package implements `DecisionProviderInterface` (`kind: 'decision'`, `decide()`),
|
|
6
|
+
independently of the conversational provider `generate()` and `stream()` methods.
|
|
7
|
+
Use it from hooks, tools, handlers, or thread endpoints; keep prompt-backed
|
|
8
|
+
conversation models configured separately with `defineModel`.
|
|
9
|
+
|
|
10
|
+
## Install and configure
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pnpm add @standardagents/typesafe
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Set `TYPESAFE_AI_API_KEY` in local `.dev.vars` or production secrets for BYOK.
|
|
17
|
+
`state.decide()` resolves scoped provider credentials and hosted routing.
|
|
18
|
+
Provider and platform destinations come only from trusted instance-admin or
|
|
19
|
+
deployment configuration; user/thread URL overrides cannot redirect inherited
|
|
20
|
+
credentials.
|
|
21
|
+
Hosted requests use the platform TypeSafe route when supported and configured;
|
|
22
|
+
platform availability requires a platform-owned TypeSafe credential.
|
|
23
|
+
|
|
24
|
+
## Decide within a thread
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { typesafe } from '@standardagents/typesafe';
|
|
28
|
+
|
|
29
|
+
const result = await state.decide({
|
|
30
|
+
provider: typesafe,
|
|
31
|
+
model: 'jev-latest',
|
|
32
|
+
context: { ticket: 'My payment failed twice. Please refund it.' },
|
|
33
|
+
questions: {
|
|
34
|
+
department: {
|
|
35
|
+
type: 'choice',
|
|
36
|
+
instructions: 'Which team should handle this ticket?',
|
|
37
|
+
options: { billing: 'Payments and refunds', technical: 'Software failures', other: null },
|
|
38
|
+
},
|
|
39
|
+
severity: {
|
|
40
|
+
type: 'score',
|
|
41
|
+
instructions: 'How disruptive is this problem?',
|
|
42
|
+
levels: ['Minor inconvenience', 'Work blocked', 'Critical outage'],
|
|
43
|
+
},
|
|
44
|
+
refund: {
|
|
45
|
+
type: 'boolean',
|
|
46
|
+
instructions: 'Does the customer explicitly request a refund?',
|
|
47
|
+
criteria: { true: 'An explicit refund request', false: 'No refund requested' },
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const team = result.answers.department.choice;
|
|
53
|
+
const refundRequested = result.answers.refund.probability >= 0.9;
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
`decide(state, options)` from `@standardagents/spec` or `@standardagents/builder`
|
|
58
|
+
is an equivalent SDK helper. In AgentBuilder, both forms record the request, response, duration,
|
|
59
|
+
status, usage, and known cost in the thread's application logs, including failure
|
|
60
|
+
information. They work outside an active conversation turn, and their logs
|
|
61
|
+
persist even before the thread has its first message. They do not read or
|
|
62
|
+
write conversation messages implicitly. If an answer belongs in conversation
|
|
63
|
+
history, explicitly call `state.injectMessage()` with the selected information.
|
|
64
|
+
Avoid logging the same decision cost again through `state.log()`.
|
|
65
|
+
|
|
66
|
+
Automatic logs, `state.log()`, and log attribution are AgentBuilder extensions,
|
|
67
|
+
not Standard Agent conformance requirements. Import log types such as
|
|
68
|
+
`ThreadLogEntry` from `@standardagents/builder`.
|
|
69
|
+
|
|
70
|
+
AgentBuilder adds optional `name` and `trigger` to the thread call to identify the operation
|
|
71
|
+
and its cause. Pass `signal` to cancel a request. Context is explicit: a string,
|
|
72
|
+
JSON object, or array. Select any relevant conversation content yourself rather
|
|
73
|
+
than assuming Jev receives the thread history. Pre-process images, audio, video,
|
|
74
|
+
and binary data into text or structured fields.
|
|
75
|
+
|
|
76
|
+
## Questions and native conversion
|
|
77
|
+
|
|
78
|
+
Every question has a stable name and `instructions`. Write the full question in
|
|
79
|
+
`instructions`: the question's map key is an answer identifier, not an instruction
|
|
80
|
+
sent to Jev. Instructions, option descriptions, rubric levels, and boolean
|
|
81
|
+
criteria may be strings, JSON objects, or arrays. Surface the domain's actual
|
|
82
|
+
options and scoring rubric in each invocation so the decision is unambiguous.
|
|
83
|
+
|
|
84
|
+
| Standard Agent request | Native TypeSafe request |
|
|
85
|
+
| --- | --- |
|
|
86
|
+
| `context` | `state`, preserving its JSON structure |
|
|
87
|
+
| `questions.<id>.type: 'choice'` with `options` | `type: 'choice'` with `criteria` |
|
|
88
|
+
| `questions.<id>.type: 'score'` with ordered `levels` | `type: 'score'` with ordered `criteria` |
|
|
89
|
+
| `questions.<id>.type: 'boolean'` with optional `criteria.true/false` | `type: 'noul'` with the same optional criteria |
|
|
90
|
+
| Each question's `instructions` and identifier | Preserved |
|
|
91
|
+
|
|
92
|
+
All questions share one state and are evaluated in one `POST /v1/systemone`
|
|
93
|
+
request. Choice accepts up to 255 options; use `null` for an option that needs no
|
|
94
|
+
extra description. Score accepts 2–10 ordered levels. Put rules and boundary
|
|
95
|
+
cases in instructions and criteria; do not put questions in provider connection
|
|
96
|
+
configuration or represent them as generated tool calls.
|
|
97
|
+
|
|
98
|
+
## Answers and thresholds
|
|
99
|
+
|
|
100
|
+
`result` contains the resolved `model`, named `answers`, standard `usage`, and
|
|
101
|
+
provider `metadata`. Every answer retains its question identifier:
|
|
102
|
+
|
|
103
|
+
- Choice: `{ type: 'choice', choice, probabilities, confidence }`.
|
|
104
|
+
- Score: `{ type: 'score', score, legend, probabilities, confidence }`. The score
|
|
105
|
+
is a probability-weighted, zero-based rubric value and can be fractional.
|
|
106
|
+
- Boolean: `{ type: 'boolean', probability }`, converted from native `noul`.
|
|
107
|
+
|
|
108
|
+
Probabilities and confidence use **0–1**. Boolean results are never coerced to
|
|
109
|
+
JavaScript booleans; choose and validate a threshold for the application's
|
|
110
|
+
policy. Confidence is provider-reported and is distinct from an option's
|
|
111
|
+
probability. Preserve the full probability distribution, score legend, and
|
|
112
|
+
confidence when storing or presenting results. Native rounded distributions can
|
|
113
|
+
sum slightly above or below one; the provider preserves them without silently
|
|
114
|
+
renormalizing. `metadata.native` retains the native response, and `metadata.rounding` records
|
|
115
|
+
probability and score precision.
|
|
116
|
+
|
|
117
|
+
## Standalone use
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
import { typesafe } from '@standardagents/typesafe';
|
|
121
|
+
|
|
122
|
+
const provider = typesafe({ apiKey: 'your-typesafe-key' });
|
|
123
|
+
const result = await provider.decide({
|
|
124
|
+
model: 'jev-latest',
|
|
125
|
+
context: 'The customer asks to cancel their plan.',
|
|
126
|
+
questions: {
|
|
127
|
+
cancel: { type: 'boolean', instructions: 'Does this request cancellation?' },
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Direct `provider.decide()` calls have no thread and create no automatic thread
|
|
133
|
+
logs. Connection configuration supports `apiKey`, `baseUrl`, `timeout`,
|
|
134
|
+
`defaultHeaders`, and a custom `fetch`; the default base is
|
|
135
|
+
`https://api.typesafe.ai/v1`. For thread calls, trusted instance-admin or
|
|
136
|
+
deployment configuration can override it with `TYPESAFE_AI_BASE_URL`.
|
|
137
|
+
Authenticated `getModels()` uses `/models`. Each attempt
|
|
138
|
+
makes one HTTP request; the caller or runtime owns retry policy. Invalid
|
|
139
|
+
questions or mismatched answers raise a `ProviderError`.
|
|
140
|
+
|
|
141
|
+
## Usage and pricing
|
|
142
|
+
|
|
143
|
+
Native `usage.input_tokens` maps to `promptTokens`, `output_tokens` to
|
|
144
|
+
`completionTokens`, and their sum to `totalTokens`. Current Jev 1.13
|
|
145
|
+
(`jev-1.13.0`, and currently `jev-latest` / `jev-preview`) costs **$0.042 per
|
|
146
|
+
million input tokens**, with free output. State is ingested once for all
|
|
147
|
+
questions: use provider-reported input usage unchanged, without multiplying it
|
|
148
|
+
by the question count. Hosted router fees are additional.
|
|
149
|
+
|
|
150
|
+
Aliases may move to new versions. `result.model` identifies the actual version;
|
|
151
|
+
re-audit rates when aliases change, or pin `jev-1.13.0` for a fixed version.
|
|
152
|
+
An unpriced resolved model does not receive an invented `usage.cost`.
|
|
153
|
+
Current context limits are 64k tokens for state plus all questions and 32k for
|
|
154
|
+
state plus the longest question. See the [TypeSafe model reference](https://docs.typesafe.ai/models)
|
|
155
|
+
and [native API reference](https://docs.typesafe.ai/api) for current limits.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { DecisionProviderInterface, ProviderFactoryConfig, DecisionQuestions, DecisionRequest, DecisionResult, ModelCapabilities, ProviderModelInfo, DecisionContext, DecisionProviderFactory } from '@standardagents/spec';
|
|
2
|
+
export { DecisionAnswer, DecisionAnswers, DecisionContext, DecisionQuestion, DecisionQuestions, DecisionRequest, DecisionResult } from '@standardagents/spec';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
|
|
5
|
+
/** Native System One adapter. The runtime owns retry policy; each attempt is one HTTP call. */
|
|
6
|
+
declare class TypeSafeProvider implements DecisionProviderInterface {
|
|
7
|
+
private readonly config;
|
|
8
|
+
readonly name = "typesafe";
|
|
9
|
+
readonly kind: "decision";
|
|
10
|
+
readonly specificationVersion: "1";
|
|
11
|
+
private readonly baseUrl;
|
|
12
|
+
constructor(config: ProviderFactoryConfig);
|
|
13
|
+
private call;
|
|
14
|
+
decide<const Q extends DecisionQuestions>(request: DecisionRequest<Q>): Promise<DecisionResult<Q>>;
|
|
15
|
+
supportsModel(modelId: string): boolean;
|
|
16
|
+
getModelCapabilities(modelId: string): Promise<ModelCapabilities | null>;
|
|
17
|
+
getModels(filter?: string): Promise<ProviderModelInfo[]>;
|
|
18
|
+
getIcon(): string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
declare const typeSafeTextSchema: z.ZodCustom<DecisionContext, DecisionContext>;
|
|
22
|
+
declare const typeSafeQuestionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
23
|
+
type: z.ZodLiteral<"choice">;
|
|
24
|
+
instructions: z.ZodCustom<DecisionContext, DecisionContext>;
|
|
25
|
+
criteria: z.ZodCustom<Record<string, DecisionContext | null>, Record<string, DecisionContext | null>>;
|
|
26
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
27
|
+
type: z.ZodLiteral<"score">;
|
|
28
|
+
instructions: z.ZodCustom<DecisionContext, DecisionContext>;
|
|
29
|
+
criteria: z.ZodArray<z.ZodCustom<DecisionContext, DecisionContext>>;
|
|
30
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
31
|
+
type: z.ZodLiteral<"noul">;
|
|
32
|
+
instructions: z.ZodCustom<DecisionContext, DecisionContext>;
|
|
33
|
+
criteria: z.ZodOptional<z.ZodObject<{
|
|
34
|
+
true: z.ZodOptional<z.ZodCustom<DecisionContext, DecisionContext>>;
|
|
35
|
+
false: z.ZodOptional<z.ZodCustom<DecisionContext, DecisionContext>>;
|
|
36
|
+
}, z.core.$strict>>;
|
|
37
|
+
}, z.core.$strict>], "type">;
|
|
38
|
+
type TypeSafeQuestion = z.infer<typeof typeSafeQuestionSchema>;
|
|
39
|
+
type TypeSafeText = z.infer<typeof typeSafeTextSchema>;
|
|
40
|
+
declare const typeSafeAnswerSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
41
|
+
type: z.ZodLiteral<"choice">;
|
|
42
|
+
choice: z.ZodString;
|
|
43
|
+
probabilities: z.ZodCustom<Record<string, number>, Record<string, number>>;
|
|
44
|
+
confidence: z.ZodNumber;
|
|
45
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
46
|
+
type: z.ZodLiteral<"score">;
|
|
47
|
+
score: z.ZodNumber;
|
|
48
|
+
legend: z.ZodCustom<Record<string, DecisionContext>, Record<string, DecisionContext>>;
|
|
49
|
+
probabilities: z.ZodCustom<Record<string, number>, Record<string, number>>;
|
|
50
|
+
confidence: z.ZodNumber;
|
|
51
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
52
|
+
type: z.ZodLiteral<"noul">;
|
|
53
|
+
noul: z.ZodNumber;
|
|
54
|
+
}, z.core.$loose>], "type">;
|
|
55
|
+
declare const typeSafeResponseSchema: z.ZodObject<{
|
|
56
|
+
model: z.ZodString;
|
|
57
|
+
answers: z.ZodCustom<Record<string, {
|
|
58
|
+
[x: string]: unknown;
|
|
59
|
+
type: "choice";
|
|
60
|
+
choice: string;
|
|
61
|
+
probabilities: Record<string, number>;
|
|
62
|
+
confidence: number;
|
|
63
|
+
} | {
|
|
64
|
+
[x: string]: unknown;
|
|
65
|
+
type: "score";
|
|
66
|
+
score: number;
|
|
67
|
+
legend: Record<string, DecisionContext>;
|
|
68
|
+
probabilities: Record<string, number>;
|
|
69
|
+
confidence: number;
|
|
70
|
+
} | {
|
|
71
|
+
[x: string]: unknown;
|
|
72
|
+
type: "noul";
|
|
73
|
+
noul: number;
|
|
74
|
+
}>, Record<string, {
|
|
75
|
+
[x: string]: unknown;
|
|
76
|
+
type: "choice";
|
|
77
|
+
choice: string;
|
|
78
|
+
probabilities: Record<string, number>;
|
|
79
|
+
confidence: number;
|
|
80
|
+
} | {
|
|
81
|
+
[x: string]: unknown;
|
|
82
|
+
type: "score";
|
|
83
|
+
score: number;
|
|
84
|
+
legend: Record<string, DecisionContext>;
|
|
85
|
+
probabilities: Record<string, number>;
|
|
86
|
+
confidence: number;
|
|
87
|
+
} | {
|
|
88
|
+
[x: string]: unknown;
|
|
89
|
+
type: "noul";
|
|
90
|
+
noul: number;
|
|
91
|
+
}>>;
|
|
92
|
+
usage: z.ZodObject<{
|
|
93
|
+
input_tokens: z.ZodNumber;
|
|
94
|
+
output_tokens: z.ZodNumber;
|
|
95
|
+
}, z.core.$loose>;
|
|
96
|
+
}, z.core.$loose>;
|
|
97
|
+
type TypeSafeAnswer = z.infer<typeof typeSafeAnswerSchema>;
|
|
98
|
+
type TypeSafeResponse = z.infer<typeof typeSafeResponseSchema>;
|
|
99
|
+
|
|
100
|
+
/** Connection configuration only. Context and questions are supplied to each decide() call. */
|
|
101
|
+
declare const typesafe: DecisionProviderFactory;
|
|
102
|
+
|
|
103
|
+
export { type TypeSafeAnswer, TypeSafeProvider, type TypeSafeQuestion, type TypeSafeResponse, type TypeSafeText, typesafe };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
// src/TypeSafeProvider.ts
|
|
2
|
+
import {
|
|
3
|
+
ProviderError as ProviderError2
|
|
4
|
+
} from "@standardagents/spec";
|
|
5
|
+
import { calculateTypeSafeUsageCost, getProviderModelPricing } from "@standardagents/provider-pricing";
|
|
6
|
+
import { z as z3 } from "zod";
|
|
7
|
+
|
|
8
|
+
// src/convert.ts
|
|
9
|
+
import { ProviderError } from "@standardagents/spec";
|
|
10
|
+
import { z as z2 } from "zod";
|
|
11
|
+
|
|
12
|
+
// src/questions.ts
|
|
13
|
+
import { z } from "zod";
|
|
14
|
+
function isRecord(value) {
|
|
15
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
|
|
16
|
+
}
|
|
17
|
+
function isJson(value, ancestors = /* @__PURE__ */ new Set()) {
|
|
18
|
+
if (value === null || typeof value === "string" || typeof value === "boolean") return true;
|
|
19
|
+
if (typeof value === "number") return Number.isFinite(value);
|
|
20
|
+
if (!Array.isArray(value) && !isRecord(value)) return false;
|
|
21
|
+
if (ancestors.has(value)) return false;
|
|
22
|
+
ancestors.add(value);
|
|
23
|
+
const valid = Object.values(value).every((child) => isJson(child, ancestors));
|
|
24
|
+
ancestors.delete(value);
|
|
25
|
+
return valid;
|
|
26
|
+
}
|
|
27
|
+
function preservedRecord(valueSchema) {
|
|
28
|
+
return z.custom(
|
|
29
|
+
(value) => isRecord(value) && Object.values(value).every((entry) => valueSchema.safeParse(entry).success),
|
|
30
|
+
"Expected a record of valid values"
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
var typeSafeTextSchema = z.custom(
|
|
34
|
+
(value) => (typeof value === "string" || Array.isArray(value) || isRecord(value)) && isJson(value),
|
|
35
|
+
"Expected text or JSON object/array"
|
|
36
|
+
);
|
|
37
|
+
var choice = z.object({
|
|
38
|
+
type: z.literal("choice"),
|
|
39
|
+
instructions: typeSafeTextSchema,
|
|
40
|
+
criteria: preservedRecord(typeSafeTextSchema.nullable()).refine((value) => Object.keys(value).length >= 1 && Object.keys(value).length <= 255, "Choice requires 1\u2013255 options")
|
|
41
|
+
}).strict();
|
|
42
|
+
var score = z.object({
|
|
43
|
+
type: z.literal("score"),
|
|
44
|
+
instructions: typeSafeTextSchema,
|
|
45
|
+
criteria: z.array(typeSafeTextSchema).min(2).max(10)
|
|
46
|
+
}).strict();
|
|
47
|
+
var noul = z.object({
|
|
48
|
+
type: z.literal("noul"),
|
|
49
|
+
instructions: typeSafeTextSchema,
|
|
50
|
+
criteria: z.object({ true: typeSafeTextSchema.optional(), false: typeSafeTextSchema.optional() }).strict().optional()
|
|
51
|
+
}).strict();
|
|
52
|
+
var typeSafeQuestionSchema = z.discriminatedUnion("type", [choice, score, noul]);
|
|
53
|
+
var probability = z.number().min(0).max(1);
|
|
54
|
+
var typeSafeAnswerSchema = z.discriminatedUnion("type", [
|
|
55
|
+
z.object({ type: z.literal("choice"), choice: z.string(), probabilities: preservedRecord(probability), confidence: probability }).passthrough(),
|
|
56
|
+
z.object({ type: z.literal("score"), score: z.number(), legend: preservedRecord(typeSafeTextSchema), probabilities: preservedRecord(probability), confidence: probability }).passthrough(),
|
|
57
|
+
z.object({ type: z.literal("noul"), noul: probability }).passthrough()
|
|
58
|
+
]);
|
|
59
|
+
var typeSafeResponseSchema = z.object({
|
|
60
|
+
model: z.string().min(1),
|
|
61
|
+
answers: preservedRecord(typeSafeAnswerSchema),
|
|
62
|
+
usage: z.object({ input_tokens: z.number().int().nonnegative(), output_tokens: z.number().int().nonnegative() }).passthrough()
|
|
63
|
+
}).passthrough();
|
|
64
|
+
|
|
65
|
+
// src/convert.ts
|
|
66
|
+
function invalidRequest(message) {
|
|
67
|
+
return new ProviderError(`TypeSafe AI: ${message}`, "invalid_request", void 0, void 0, { origin: "provider:typesafe" });
|
|
68
|
+
}
|
|
69
|
+
var standardQuestion = z2.discriminatedUnion("type", [
|
|
70
|
+
z2.object({ type: z2.literal("choice"), instructions: typeSafeTextSchema, options: preservedRecord(typeSafeTextSchema.nullable()) }).strict(),
|
|
71
|
+
z2.object({ type: z2.literal("score"), instructions: typeSafeTextSchema, levels: z2.array(typeSafeTextSchema) }).strict(),
|
|
72
|
+
z2.object({ type: z2.literal("boolean"), instructions: typeSafeTextSchema, criteria: z2.object({ true: typeSafeTextSchema.optional(), false: typeSafeTextSchema.optional() }).strict().optional() }).strict()
|
|
73
|
+
]);
|
|
74
|
+
var requestSchema = z2.object({
|
|
75
|
+
model: z2.string().trim().min(1),
|
|
76
|
+
context: typeSafeTextSchema,
|
|
77
|
+
questions: preservedRecord(standardQuestion).refine((value) => Object.keys(value).length > 0, "At least one question is required")
|
|
78
|
+
});
|
|
79
|
+
function convertTypeSafeRequest(request) {
|
|
80
|
+
const parsed = requestSchema.safeParse(request);
|
|
81
|
+
if (!parsed.success) throw invalidRequest(parsed.error.message);
|
|
82
|
+
const entries = [];
|
|
83
|
+
for (const [id, question] of Object.entries(parsed.data.questions)) {
|
|
84
|
+
const native = question.type === "choice" ? { type: "choice", instructions: question.instructions, criteria: question.options } : question.type === "score" ? { type: "score", instructions: question.instructions, criteria: question.levels } : { type: "noul", instructions: question.instructions, ...question.criteria ? { criteria: question.criteria } : {} };
|
|
85
|
+
const validated = typeSafeQuestionSchema.safeParse(native);
|
|
86
|
+
if (!validated.success) throw invalidRequest(`Invalid question ${id}: ${validated.error.message}`);
|
|
87
|
+
entries.push([id, validated.data]);
|
|
88
|
+
}
|
|
89
|
+
return { model: parsed.data.model, state: parsed.data.context, questions: Object.fromEntries(entries) };
|
|
90
|
+
}
|
|
91
|
+
function invalidResponse(detail) {
|
|
92
|
+
throw new ProviderError(`TypeSafe AI returned invalid answers: ${detail}`, "server_error", void 0, void 0, { origin: "provider:typesafe" });
|
|
93
|
+
}
|
|
94
|
+
function validateTypeSafeAnswers(response, questions) {
|
|
95
|
+
const ids = Object.keys(questions);
|
|
96
|
+
if (Object.keys(response.answers).length !== ids.length) invalidResponse("question/answer count mismatch");
|
|
97
|
+
for (const [id, question] of Object.entries(questions)) {
|
|
98
|
+
const answer = response.answers[id];
|
|
99
|
+
if (!answer || answer.type !== question.type) invalidResponse(`missing or mismatched answer for ${id}`);
|
|
100
|
+
if (question.type === "noul" || answer.type === "noul") continue;
|
|
101
|
+
const keys = question.type === "choice" ? Object.keys(question.criteria) : question.criteria.map((_, index) => String(index));
|
|
102
|
+
if (Object.keys(answer.probabilities).length !== keys.length || keys.some((key) => !Object.hasOwn(answer.probabilities, key))) invalidResponse(`probability options differ for ${id}`);
|
|
103
|
+
const sum = Object.values(answer.probabilities).reduce((total, value) => total + value, 0);
|
|
104
|
+
if (Math.abs(sum - 1) > keys.length * 5e-3 + 1e-8) invalidResponse(`invalid probability distribution for ${id}`);
|
|
105
|
+
if (answer.type === "choice" && !keys.includes(answer.choice)) invalidResponse(`unknown choice for ${id}`);
|
|
106
|
+
if (answer.type === "score") {
|
|
107
|
+
if (answer.score < 0 || answer.score > keys.length - 1) invalidResponse(`score outside rubric for ${id}`);
|
|
108
|
+
if (Object.keys(answer.legend).length !== keys.length || keys.some((key) => !Object.hasOwn(answer.legend, key))) invalidResponse(`legend differs for ${id}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function assertAnswerTypes(answers, questions) {
|
|
113
|
+
if (Object.keys(answers).length !== Object.keys(questions).length) invalidResponse("question/answer count mismatch");
|
|
114
|
+
for (const [id, question] of Object.entries(questions)) {
|
|
115
|
+
if (!Object.hasOwn(answers, id) || answers[id].type !== question.type) invalidResponse(`answer type differs for ${id}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function convertTypeSafeAnswers(response, questions) {
|
|
119
|
+
const entries = Object.entries(response.answers).map(([id, answer]) => [
|
|
120
|
+
id,
|
|
121
|
+
answer.type === "noul" ? { type: "boolean", probability: answer.noul } : answer
|
|
122
|
+
]);
|
|
123
|
+
const answers = Object.fromEntries(entries);
|
|
124
|
+
assertAnswerTypes(answers, questions);
|
|
125
|
+
return answers;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// src/icons.ts
|
|
129
|
+
var TYPESAFE_ICON = "data:image/png;base64,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";
|
|
130
|
+
|
|
131
|
+
// src/TypeSafeProvider.ts
|
|
132
|
+
var capabilities = {
|
|
133
|
+
supportsImages: false,
|
|
134
|
+
supportsToolCalls: false,
|
|
135
|
+
supportsStreaming: false,
|
|
136
|
+
supportsJsonMode: false,
|
|
137
|
+
maxContextTokens: 64e3
|
|
138
|
+
};
|
|
139
|
+
var modelsSchema = z3.object({ models: z3.array(z3.object({ name: z3.string(), description: z3.string().optional() })) });
|
|
140
|
+
var TypeSafeProvider = class {
|
|
141
|
+
constructor(config) {
|
|
142
|
+
this.config = config;
|
|
143
|
+
this.baseUrl = (config.baseUrl ?? "https://api.typesafe.ai/v1").replace(/\/+$/, "");
|
|
144
|
+
}
|
|
145
|
+
name = "typesafe";
|
|
146
|
+
kind = "decision";
|
|
147
|
+
specificationVersion = "1";
|
|
148
|
+
baseUrl;
|
|
149
|
+
async call(path, body, signal) {
|
|
150
|
+
signal?.throwIfAborted();
|
|
151
|
+
const timeout = AbortSignal.timeout(this.config.timeout ?? 6e4);
|
|
152
|
+
const combined = signal ? AbortSignal.any([signal, timeout]) : timeout;
|
|
153
|
+
try {
|
|
154
|
+
const response = await (this.config.fetch ?? fetch)(`${this.baseUrl}${path}`, {
|
|
155
|
+
method: body ? "POST" : "GET",
|
|
156
|
+
headers: { ...this.config.defaultHeaders, "Content-Type": "application/json", Authorization: `Bearer ${this.config.apiKey}` },
|
|
157
|
+
...body ? { body: JSON.stringify(body) } : {},
|
|
158
|
+
signal: combined
|
|
159
|
+
});
|
|
160
|
+
if (!response.ok) {
|
|
161
|
+
const status = response.status;
|
|
162
|
+
const retry = response.headers.get("retry-after");
|
|
163
|
+
const retryAfter = retry === null ? void 0 : /^\d+(\.\d+)?$/.test(retry) ? Number(retry) : Math.max(0, (Date.parse(retry) - Date.now()) / 1e3);
|
|
164
|
+
let source;
|
|
165
|
+
try {
|
|
166
|
+
source = await response.json();
|
|
167
|
+
} catch {
|
|
168
|
+
}
|
|
169
|
+
const router = typeof source === "object" && source !== null && "source" in source && source.source === "standard_agents_router";
|
|
170
|
+
throw new ProviderError2(`TypeSafe AI request failed (HTTP ${status})`, status === 401 || status === 403 ? "auth_error" : status === 429 ? "rate_limit" : status >= 500 ? "server_error" : "invalid_request", status, Number.isFinite(retryAfter) ? retryAfter : void 0, { cause: source, origin: router ? "platform-router" : "provider:typesafe" });
|
|
171
|
+
}
|
|
172
|
+
return await response.json();
|
|
173
|
+
} catch (error) {
|
|
174
|
+
if (signal?.aborted) throw signal.reason;
|
|
175
|
+
if (error instanceof ProviderError2) throw error;
|
|
176
|
+
throw new ProviderError2(timeout.aborted ? "TypeSafe AI request timed out" : "TypeSafe AI transport or response failed", timeout.aborted ? "timeout" : "server_error", void 0, void 0, { cause: error, origin: "provider:typesafe" });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
async decide(request) {
|
|
180
|
+
const body = convertTypeSafeRequest(request);
|
|
181
|
+
const raw = await this.call("/systemone", body, request.signal);
|
|
182
|
+
const parsed = typeSafeResponseSchema.safeParse(raw);
|
|
183
|
+
if (!parsed.success) throw new ProviderError2("TypeSafe AI returned an invalid decision response", "server_error", void 0, void 0, { cause: parsed.error, origin: "provider:typesafe" });
|
|
184
|
+
const response = parsed.data;
|
|
185
|
+
validateTypeSafeAnswers(response, body.questions);
|
|
186
|
+
const promptTokens = response.usage.input_tokens;
|
|
187
|
+
const completionTokens = response.usage.output_tokens;
|
|
188
|
+
const cost = calculateTypeSafeUsageCost(response.model, { promptTokens, completionTokens });
|
|
189
|
+
return {
|
|
190
|
+
model: response.model,
|
|
191
|
+
answers: convertTypeSafeAnswers(response, request.questions),
|
|
192
|
+
usage: { promptTokens, completionTokens, totalTokens: promptTokens + completionTokens, provider: this.name, ...cost === void 0 ? {} : { cost } },
|
|
193
|
+
metadata: { native: raw, rounding: { probabilities: 2, score: 2 } }
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
supportsModel(modelId) {
|
|
197
|
+
return /^jev-(?:latest|preview|\d+\.\d+\.\d+)$/.test(modelId);
|
|
198
|
+
}
|
|
199
|
+
async getModelCapabilities(modelId) {
|
|
200
|
+
return this.supportsModel(modelId) ? { ...capabilities } : null;
|
|
201
|
+
}
|
|
202
|
+
async getModels(filter) {
|
|
203
|
+
const parsed = modelsSchema.safeParse(await this.call("/models"));
|
|
204
|
+
if (!parsed.success) throw new ProviderError2("TypeSafe AI returned an invalid model catalog", "server_error");
|
|
205
|
+
return parsed.data.models.filter((model) => !filter || `${model.name} ${model.description ?? ""}`.toLowerCase().includes(filter.toLowerCase())).map((model) => {
|
|
206
|
+
const pricing = getProviderModelPricing("typesafe", model.name);
|
|
207
|
+
return { id: model.name, name: model.name, description: model.description, contextLength: 64e3, capabilities: { ...capabilities }, ...pricing ? { inputPrice: pricing.inputPerMillion, outputPrice: pricing.outputPerMillion } : {} };
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
getIcon() {
|
|
211
|
+
return TYPESAFE_ICON;
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
// src/index.ts
|
|
216
|
+
var typesafe = Object.assign(
|
|
217
|
+
(config) => new TypeSafeProvider(config),
|
|
218
|
+
{ configSlots: {
|
|
219
|
+
apiKey: { type: "secret", defaultEnv: "TYPESAFE_AI_API_KEY", required: true },
|
|
220
|
+
baseUrl: { type: "url", defaultEnv: "TYPESAFE_AI_BASE_URL", default: "https://api.typesafe.ai/v1" }
|
|
221
|
+
} }
|
|
222
|
+
);
|
|
223
|
+
export {
|
|
224
|
+
TypeSafeProvider,
|
|
225
|
+
typesafe
|
|
226
|
+
};
|
|
227
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/TypeSafeProvider.ts","../src/convert.ts","../src/questions.ts","../src/icons.ts","../src/index.ts"],"sourcesContent":["import {\n ProviderError, type DecisionProviderInterface, type DecisionQuestions,\n type DecisionRequest, type DecisionResult, type ModelCapabilities,\n type ProviderFactoryConfig, type ProviderModelInfo,\n} from '@standardagents/spec';\nimport { calculateTypeSafeUsageCost, getProviderModelPricing } from '@standardagents/provider-pricing';\nimport { z } from 'zod';\nimport { convertTypeSafeRequest, validateTypeSafeAnswers, convertTypeSafeAnswers } from './convert';\nimport { typeSafeResponseSchema } from './questions';\nimport { TYPESAFE_ICON } from './icons';\n\nconst capabilities: ModelCapabilities = {\n supportsImages: false, supportsToolCalls: false, supportsStreaming: false,\n supportsJsonMode: false, maxContextTokens: 64000,\n};\nconst modelsSchema = z.object({ models: z.array(z.object({ name: z.string(), description: z.string().optional() })) });\n\n/** Native System One adapter. The runtime owns retry policy; each attempt is one HTTP call. */\nexport class TypeSafeProvider implements DecisionProviderInterface {\n readonly name = 'typesafe';\n readonly kind = 'decision' as const;\n readonly specificationVersion = '1' as const;\n private readonly baseUrl: string;\n constructor(private readonly config: ProviderFactoryConfig) {\n this.baseUrl = (config.baseUrl ?? 'https://api.typesafe.ai/v1').replace(/\\/+$/, '');\n }\n private async call(path: string, body?: Record<string, unknown>, signal?: AbortSignal): Promise<unknown> {\n signal?.throwIfAborted();\n const timeout = AbortSignal.timeout(this.config.timeout ?? 60000);\n const combined = signal ? AbortSignal.any([signal, timeout]) : timeout;\n try {\n const response = await (this.config.fetch ?? fetch)(`${this.baseUrl}${path}`, {\n method: body ? 'POST' : 'GET',\n headers: { ...this.config.defaultHeaders, 'Content-Type': 'application/json', Authorization: `Bearer ${this.config.apiKey}` },\n ...(body ? { body: JSON.stringify(body) } : {}), signal: combined,\n });\n if (!response.ok) {\n const status = response.status;\n const retry = response.headers.get('retry-after');\n const retryAfter = retry === null ? undefined : /^\\d+(\\.\\d+)?$/.test(retry) ? Number(retry) : Math.max(0, (Date.parse(retry) - Date.now()) / 1000);\n let source: unknown;\n try { source = await response.json(); } catch { /* An upstream may send an HTML error. */ }\n const router = typeof source === 'object' && source !== null && 'source' in source && source.source === 'standard_agents_router';\n throw new ProviderError(`TypeSafe AI request failed (HTTP ${status})`, status === 401 || status === 403 ? 'auth_error' : status === 429 ? 'rate_limit' : status >= 500 ? 'server_error' : 'invalid_request', status, Number.isFinite(retryAfter) ? retryAfter : undefined, { cause: source, origin: router ? 'platform-router' : 'provider:typesafe' });\n }\n return await response.json();\n } catch (error) {\n if (signal?.aborted) throw signal.reason;\n if (error instanceof ProviderError) throw error;\n throw new ProviderError(timeout.aborted ? 'TypeSafe AI request timed out' : 'TypeSafe AI transport or response failed', timeout.aborted ? 'timeout' : 'server_error', undefined, undefined, { cause: error, origin: 'provider:typesafe' });\n }\n }\n async decide<const Q extends DecisionQuestions>(request: DecisionRequest<Q>): Promise<DecisionResult<Q>> {\n const body = convertTypeSafeRequest(request);\n const raw = await this.call('/systemone', body, request.signal);\n const parsed = typeSafeResponseSchema.safeParse(raw);\n if (!parsed.success) throw new ProviderError('TypeSafe AI returned an invalid decision response', 'server_error', undefined, undefined, { cause: parsed.error, origin: 'provider:typesafe' });\n const response = parsed.data;\n validateTypeSafeAnswers(response, body.questions);\n const promptTokens = response.usage.input_tokens;\n const completionTokens = response.usage.output_tokens;\n const cost = calculateTypeSafeUsageCost(response.model, { promptTokens, completionTokens });\n return {\n model: response.model,\n answers: convertTypeSafeAnswers(response, request.questions),\n usage: { promptTokens, completionTokens, totalTokens: promptTokens + completionTokens, provider: this.name, ...(cost === undefined ? {} : { cost }) },\n metadata: { native: raw, rounding: { probabilities: 2, score: 2 } },\n };\n }\n supportsModel(modelId: string): boolean { return /^jev-(?:latest|preview|\\d+\\.\\d+\\.\\d+)$/.test(modelId); }\n async getModelCapabilities(modelId: string): Promise<ModelCapabilities | null> { return this.supportsModel(modelId) ? { ...capabilities } : null; }\n async getModels(filter?: string): Promise<ProviderModelInfo[]> {\n const parsed = modelsSchema.safeParse(await this.call('/models'));\n if (!parsed.success) throw new ProviderError('TypeSafe AI returned an invalid model catalog', 'server_error');\n return parsed.data.models.filter(model => !filter || `${model.name} ${model.description ?? ''}`.toLowerCase().includes(filter.toLowerCase())).map(model => {\n const pricing = getProviderModelPricing('typesafe', model.name);\n return { id: model.name, name: model.name, description: model.description, contextLength: 64000, capabilities: { ...capabilities }, ...(pricing ? { inputPrice: pricing.inputPerMillion, outputPrice: pricing.outputPerMillion } : {}) };\n });\n }\n getIcon(): string { return TYPESAFE_ICON; }\n}\n","import { ProviderError, type DecisionQuestions, type DecisionRequest, type DecisionAnswers, type DecisionAnswer } from '@standardagents/spec';\nimport { z } from 'zod';\nimport { typeSafeQuestionSchema, typeSafeTextSchema, preservedRecord, type TypeSafeQuestion, type TypeSafeResponse } from './questions';\n\nexport function invalidRequest(message: string): ProviderError {\n return new ProviderError(`TypeSafe AI: ${message}`, 'invalid_request', undefined, undefined, { origin: 'provider:typesafe' });\n}\nconst standardQuestion = z.discriminatedUnion('type', [\n z.object({ type: z.literal('choice'), instructions: typeSafeTextSchema, options: preservedRecord(typeSafeTextSchema.nullable()) }).strict(),\n z.object({ type: z.literal('score'), instructions: typeSafeTextSchema, levels: z.array(typeSafeTextSchema) }).strict(),\n z.object({ type: z.literal('boolean'), instructions: typeSafeTextSchema, criteria: z.object({ true: typeSafeTextSchema.optional(), false: typeSafeTextSchema.optional() }).strict().optional() }).strict(),\n]);\nconst requestSchema = z.object({\n model: z.string().trim().min(1),\n context: typeSafeTextSchema,\n questions: preservedRecord(standardQuestion).refine(value => Object.keys(value).length > 0, 'At least one question is required'),\n});\n\n/** Native JSON structure is retained, with only the standard primitive field names translated. */\nexport function convertTypeSafeRequest(request: DecisionRequest) {\n const parsed = requestSchema.safeParse(request);\n if (!parsed.success) throw invalidRequest(parsed.error.message);\n const entries: [string, TypeSafeQuestion][] = [];\n for (const [id, question] of Object.entries(parsed.data.questions)) {\n const native = question.type === 'choice'\n ? { type: 'choice', instructions: question.instructions, criteria: question.options }\n : question.type === 'score'\n ? { type: 'score', instructions: question.instructions, criteria: question.levels }\n : { type: 'noul', instructions: question.instructions, ...(question.criteria ? { criteria: question.criteria } : {}) };\n const validated = typeSafeQuestionSchema.safeParse(native);\n if (!validated.success) throw invalidRequest(`Invalid question ${id}: ${validated.error.message}`);\n entries.push([id, validated.data]);\n }\n return { model: parsed.data.model, state: parsed.data.context, questions: Object.fromEntries(entries) };\n}\n\nfunction invalidResponse(detail: string): never {\n throw new ProviderError(`TypeSafe AI returned invalid answers: ${detail}`, 'server_error', undefined, undefined, { origin: 'provider:typesafe' });\n}\n\n/** Validate correspondence while preserving upstream rounding (never renormalize). */\nexport function validateTypeSafeAnswers(response: TypeSafeResponse, questions: Record<string, TypeSafeQuestion>): void {\n const ids = Object.keys(questions);\n if (Object.keys(response.answers).length !== ids.length) invalidResponse('question/answer count mismatch');\n for (const [id, question] of Object.entries(questions)) {\n const answer = response.answers[id];\n if (!answer || answer.type !== question.type) invalidResponse(`missing or mismatched answer for ${id}`);\n if (question.type === 'noul' || answer.type === 'noul') continue;\n const keys = question.type === 'choice' ? Object.keys(question.criteria) : question.criteria.map((_, index) => String(index));\n if (Object.keys(answer.probabilities).length !== keys.length || keys.some(key => !Object.hasOwn(answer.probabilities, key))) invalidResponse(`probability options differ for ${id}`);\n const sum = Object.values(answer.probabilities).reduce((total, value) => total + value, 0);\n // Native probabilities are rounded to 2dp, so the sum can differ by up to 0.005 per option.\n if (Math.abs(sum - 1) > keys.length * 0.005 + 1e-8) invalidResponse(`invalid probability distribution for ${id}`);\n if (answer.type === 'choice' && !keys.includes(answer.choice)) invalidResponse(`unknown choice for ${id}`);\n if (answer.type === 'score') {\n if (answer.score < 0 || answer.score > keys.length - 1) invalidResponse(`score outside rubric for ${id}`);\n if (Object.keys(answer.legend).length !== keys.length || keys.some(key => !Object.hasOwn(answer.legend, key))) invalidResponse(`legend differs for ${id}`);\n }\n }\n}\n\n/** Narrow the mapped result only after validating the discriminant for every named question. */\nfunction assertAnswerTypes<Q extends DecisionQuestions>(answers: Record<string, DecisionAnswer>, questions: Q): asserts answers is DecisionAnswers<Q> {\n if (Object.keys(answers).length !== Object.keys(questions).length) invalidResponse('question/answer count mismatch');\n for (const [id, question] of Object.entries(questions)) {\n if (!Object.hasOwn(answers, id) || answers[id].type !== question.type) invalidResponse(`answer type differs for ${id}`);\n }\n}\nexport function convertTypeSafeAnswers<Q extends DecisionQuestions>(response: TypeSafeResponse, questions: Q): DecisionAnswers<Q> {\n const entries: [string, DecisionAnswer][] = Object.entries(response.answers).map(([id, answer]) => [id,\n answer.type === 'noul' ? { type: 'boolean', probability: answer.noul } : answer,\n ]);\n const answers = Object.fromEntries(entries);\n assertAnswerTypes(answers, questions);\n return answers;\n}\n","import { z } from 'zod';\nimport type { DecisionContext } from '@standardagents/spec';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);\n}\nfunction isJson(value: unknown, ancestors = new Set<object>()): boolean {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') return true;\n if (typeof value === 'number') return Number.isFinite(value);\n if (!Array.isArray(value) && !isRecord(value)) return false;\n if (ancestors.has(value)) return false;\n ancestors.add(value);\n const valid = Object.values(value).every(child => isJson(child, ancestors));\n ancestors.delete(value);\n return valid;\n}\n\n// Zod records rebuild objects and omit own __proto__ keys. These are legitimate\n// opaque JSON data/answer IDs, so validate without reconstructing their maps.\nexport function preservedRecord<T extends z.ZodType>(valueSchema: T) {\n return z.custom<Record<string, z.output<T>>>(value =>\n isRecord(value) && Object.values(value).every(entry => valueSchema.safeParse(entry).success),\n 'Expected a record of valid values');\n}\nexport const typeSafeTextSchema = z.custom<DecisionContext>(value =>\n (typeof value === 'string' || Array.isArray(value) || isRecord(value)) && isJson(value),\n 'Expected text or JSON object/array');\n\nconst choice = z.object({\n type: z.literal('choice'),\n instructions: typeSafeTextSchema,\n criteria: preservedRecord(typeSafeTextSchema.nullable()).refine(value => Object.keys(value).length >= 1 && Object.keys(value).length <= 255, 'Choice requires 1–255 options'),\n}).strict();\nconst score = z.object({\n type: z.literal('score'),\n instructions: typeSafeTextSchema,\n criteria: z.array(typeSafeTextSchema).min(2).max(10),\n}).strict();\nconst noul = z.object({\n type: z.literal('noul'),\n instructions: typeSafeTextSchema,\n criteria: z.object({ true: typeSafeTextSchema.optional(), false: typeSafeTextSchema.optional() }).strict().optional(),\n}).strict();\nexport const typeSafeQuestionSchema = z.discriminatedUnion('type', [choice, score, noul]);\nexport type TypeSafeQuestion = z.infer<typeof typeSafeQuestionSchema>;\nexport type TypeSafeText = z.infer<typeof typeSafeTextSchema>;\n\nconst probability = z.number().min(0).max(1);\nexport const typeSafeAnswerSchema = z.discriminatedUnion('type', [\n z.object({ type: z.literal('choice'), choice: z.string(), probabilities: preservedRecord(probability), confidence: probability }).passthrough(),\n z.object({ type: z.literal('score'), score: z.number(), legend: preservedRecord(typeSafeTextSchema), probabilities: preservedRecord(probability), confidence: probability }).passthrough(),\n z.object({ type: z.literal('noul'), noul: probability }).passthrough(),\n]);\nexport const typeSafeResponseSchema = z.object({\n model: z.string().min(1),\n answers: preservedRecord(typeSafeAnswerSchema),\n usage: z.object({ input_tokens: z.number().int().nonnegative(), output_tokens: z.number().int().nonnegative() }).passthrough(),\n}).passthrough();\nexport type TypeSafeAnswer = z.infer<typeof typeSafeAnswerSchema>;\nexport type TypeSafeResponse = z.infer<typeof typeSafeResponseSchema>;\n","// Official square TypeSafe AI favicon from docs.typesafe.ai (2026-10-06).\nexport const TYPESAFE_ICON = \"data:image/png;base64,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\";\n","import type { ProviderFactoryConfig, DecisionProviderFactory } from '@standardagents/spec';\nimport { TypeSafeProvider } from './TypeSafeProvider';\n\n/** Connection configuration only. Context and questions are supplied to each decide() call. */\nexport const typesafe: DecisionProviderFactory = Object.assign(\n (config: ProviderFactoryConfig) => new TypeSafeProvider(config),\n { configSlots: {\n apiKey: { type: 'secret' as const, defaultEnv: 'TYPESAFE_AI_API_KEY', required: true },\n baseUrl: { type: 'url' as const, defaultEnv: 'TYPESAFE_AI_BASE_URL', default: 'https://api.typesafe.ai/v1' },\n } },\n);\nexport { TypeSafeProvider } from './TypeSafeProvider';\nexport type { TypeSafeQuestion, TypeSafeAnswer, TypeSafeResponse, TypeSafeText } from './questions';\nexport type { DecisionRequest, DecisionResult, DecisionQuestions, DecisionQuestion, DecisionAnswers, DecisionAnswer, DecisionContext } from '@standardagents/spec';\n"],"mappings":"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","names":["ProviderError","z","z","z","z","ProviderError"]}
|
package/package.json
CHANGED
|
@@ -1,11 +1,51 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@standardagents/typesafe",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
3
|
+
"version": "0.42.1",
|
|
4
|
+
"private": false,
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public",
|
|
7
|
+
"registry": "https://registry.npmjs.org/"
|
|
8
|
+
},
|
|
5
9
|
"type": "module",
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
10
|
+
"description": "TypeSafe AI Jev decision provider for Standard Agents",
|
|
11
|
+
"main": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"README.md"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsup",
|
|
25
|
+
"dev": "tsup --watch",
|
|
26
|
+
"typecheck": "tsc --noEmit",
|
|
27
|
+
"test": "vitest --config vitest.config.ts",
|
|
28
|
+
"test:run": "vitest run --config vitest.config.ts"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@standardagents/provider-pricing": "0.42.1",
|
|
32
|
+
"zod": "^4.3.5"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"@standardagents/spec": "^0.42.1"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@standardagents/spec": "0.42.1",
|
|
39
|
+
"tsup": "^8.3.5",
|
|
40
|
+
"typescript": "^5.9.0"
|
|
41
|
+
},
|
|
42
|
+
"keywords": [
|
|
43
|
+
"standardagents",
|
|
44
|
+
"typesafe",
|
|
45
|
+
"jev",
|
|
46
|
+
"provider",
|
|
47
|
+
"decisions"
|
|
48
|
+
],
|
|
9
49
|
"author": "FormKit Inc.",
|
|
10
50
|
"license": "UNLICENSED"
|
|
11
51
|
}
|
package/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
throw new Error('@standardagents/typesafe@0.0.0 is a bootstrap placeholder. Install a production release to use TypeSafe AI.');
|