@pi-in-go/pigpen-jev 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CREDITS.md +22 -0
- package/LICENSE +22 -0
- package/README.md +237 -0
- package/extensions/jev/ask.go +166 -0
- package/extensions/jev/ask_test.go +218 -0
- package/extensions/jev/backend.go +128 -0
- package/extensions/jev/bench_test.go +64 -0
- package/extensions/jev/boundaries_test.go +159 -0
- package/extensions/jev/command.go +224 -0
- package/extensions/jev/commands_test.go +214 -0
- package/extensions/jev/config.go +450 -0
- package/extensions/jev/errors_test.go +191 -0
- package/extensions/jev/extension.go +391 -0
- package/extensions/jev/fakehost_test.go +548 -0
- package/extensions/jev/gate.go +125 -0
- package/extensions/jev/gate_test.go +610 -0
- package/extensions/jev/gatekey_test.go +24 -0
- package/extensions/jev/go.mod +9 -0
- package/extensions/jev/go.sum +2 -0
- package/extensions/jev/go.work +10 -0
- package/extensions/jev/helpers_test.go +404 -0
- package/extensions/jev/memo.go +88 -0
- package/extensions/jev/output.go +89 -0
- package/extensions/jev/output_test.go +187 -0
- package/extensions/jev/ownmodel_test.go +118 -0
- package/extensions/jev/render.go +136 -0
- package/extensions/jev/review_test.go +310 -0
- package/extensions/jev/source_test.go +57 -0
- package/extensions/jev/text.go +174 -0
- package/extensions/jev/trust_test.go +335 -0
- package/extensions/jev/types.go +227 -0
- package/libs/typesafe/CONTRACT.md +125 -0
- package/libs/typesafe/CREDITS.md +37 -0
- package/libs/typesafe/LICENSE +23 -0
- package/libs/typesafe/README.md +19 -0
- package/libs/typesafe/go.mod +3 -0
- package/libs/typesafe/libraries/ownmodel/backend_test.go +496 -0
- package/libs/typesafe/libraries/ownmodel/canon.go +190 -0
- package/libs/typesafe/libraries/ownmodel/convert.go +199 -0
- package/libs/typesafe/libraries/ownmodel/doc.go +15 -0
- package/libs/typesafe/libraries/ownmodel/equivalence_test.go +199 -0
- package/libs/typesafe/libraries/ownmodel/helpers_test.go +155 -0
- package/libs/typesafe/libraries/ownmodel/mutation_test.go +31 -0
- package/libs/typesafe/libraries/ownmodel/ownmodel.go +225 -0
- package/libs/typesafe/libraries/ownmodel/plan.go +442 -0
- package/libs/typesafe/libraries/ownmodel/run.go +288 -0
- package/libs/typesafe/libraries/ownmodel/schema_test.go +254 -0
- package/libs/typesafe/libraries/ownmodel/twins_test.go +169 -0
- package/libs/typesafe/libraries/ownmodel/utils_test.go +125 -0
- package/libs/typesafe/libraries/pigmodel/pigmodel.go +264 -0
- package/libs/typesafe/libraries/pigmodel/pigmodel_test.go +410 -0
- package/libs/typesafe/libraries/typesafe/answers.go +268 -0
- package/libs/typesafe/libraries/typesafe/api_response_test.go +113 -0
- package/libs/typesafe/libraries/typesafe/batch.go +80 -0
- package/libs/typesafe/libraries/typesafe/batch_test.go +133 -0
- package/libs/typesafe/libraries/typesafe/bench_test.go +71 -0
- package/libs/typesafe/libraries/typesafe/client.go +561 -0
- package/libs/typesafe/libraries/typesafe/client_test.go +495 -0
- package/libs/typesafe/libraries/typesafe/crosscheck_test.go +464 -0
- package/libs/typesafe/libraries/typesafe/crosscheck_workflowevals_test.go +219 -0
- package/libs/typesafe/libraries/typesafe/doc.go +27 -0
- package/libs/typesafe/libraries/typesafe/entry.go +142 -0
- package/libs/typesafe/libraries/typesafe/env.go +11 -0
- package/libs/typesafe/libraries/typesafe/errors.go +310 -0
- package/libs/typesafe/libraries/typesafe/errors_test.go +175 -0
- package/libs/typesafe/libraries/typesafe/helpers_test.go +294 -0
- package/libs/typesafe/libraries/typesafe/live_test.go +96 -0
- package/libs/typesafe/libraries/typesafe/logging.go +160 -0
- package/libs/typesafe/libraries/typesafe/logging_test.go +259 -0
- package/libs/typesafe/libraries/typesafe/marshal_test.go +112 -0
- package/libs/typesafe/libraries/typesafe/mutation_test.go +39 -0
- package/libs/typesafe/libraries/typesafe/questions.go +490 -0
- package/libs/typesafe/libraries/typesafe/questions_test.go +166 -0
- package/libs/typesafe/libraries/typesafe/regressions_test.go +159 -0
- package/libs/typesafe/libraries/typesafe/reliability_test.go +649 -0
- package/libs/typesafe/libraries/typesafe/retry.go +350 -0
- package/libs/typesafe/libraries/typesafe/retry_test.go +297 -0
- package/libs/typesafe/libraries/typesafe/runtime_test.go +26 -0
- package/libs/typesafe/libraries/typesafe/transport_test.go +163 -0
- package/libs/typesafe/libraries/typesafe/twins_test.go +127 -0
- package/libs/typesafe/libraries/typesafe/types_test.go +165 -0
- package/libs/typesafe/libraries/typesafe/version.go +10 -0
- package/libs/typesafe/package.json +37 -0
- package/libs/typesafe/provenance.json +49 -0
- package/package.json +42 -0
- package/port/PORT.md +107 -0
- package/port/e2e/gate-and-output.py +35 -0
- package/port/e2e/jev-ask.py +36 -0
- package/port/e2e/model-switch.py +44 -0
- package/port/e2e/off-by-default.py +34 -0
- package/port/gen-scenarios.py +103 -0
- package/port/golden/cache-identical-calls.jsonl +30 -0
- package/port/golden/clear.jsonl +22 -0
- package/port/golden/commands.jsonl +43 -0
- package/port/golden/enforce-accept.jsonl +23 -0
- package/port/golden/enforce-decline.jsonl +22 -0
- package/port/golden/jev-ask.jsonl +20 -0
- package/port/golden/output-advice.jsonl +23 -0
- package/port/golden/output-leak.jsonl +24 -0
- package/port/golden/output-low-confidence.jsonl +22 -0
- package/port/golden/shadow-flagged.jsonl +23 -0
- package/port/golden/unjudged-tools.jsonl +19 -0
- package/port/golden/write-elision.jsonl +21 -0
- package/port/mutate-unit.py +63 -0
- package/port/mutations.json +578 -0
- package/port/oracle/LICENSE +21 -0
- package/port/oracle/README.md +181 -0
- package/port/oracle/SHA256SUMS +8 -0
- package/port/oracle/package.json +43 -0
- package/port/oracle/src/client.ts +409 -0
- package/port/oracle/src/config.ts +363 -0
- package/port/oracle/src/gate.ts +229 -0
- package/port/oracle/src/index.ts +649 -0
- package/port/oracle/src/output.ts +163 -0
- package/port/red-run.log +309 -0
- package/port/scenarios/cache-identical-calls.json +71 -0
- package/port/scenarios/clear.json +61 -0
- package/port/scenarios/commands.json +119 -0
- package/port/scenarios/enforce-accept.json +66 -0
- package/port/scenarios/enforce-decline.json +57 -0
- package/port/scenarios/jev-ask.json +83 -0
- package/port/scenarios/output-advice.json +61 -0
- package/port/scenarios/output-leak.json +61 -0
- package/port/scenarios/output-low-confidence.json +61 -0
- package/port/scenarios/shadow-flagged.json +61 -0
- package/port/scenarios/unjudged-tools.json +55 -0
- package/port/scenarios/write-elision.json +53 -0
- package/provenance.json +18 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
package typesafe
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"context"
|
|
5
|
+
"encoding/json"
|
|
6
|
+
"errors"
|
|
7
|
+
"net/http"
|
|
8
|
+
"strings"
|
|
9
|
+
"testing"
|
|
10
|
+
"testing/synctest"
|
|
11
|
+
"time"
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
func TestReleaseRegressions_ReplacesMixedCaseDefaultsAndProtectsEverySDKHeaderOnEveryAttempt(t *testing.T) {
|
|
15
|
+
twin(t, "release-regressions.test.ts | release regressions replaces mixed-case defaults and protects every SDK header on every attempt")
|
|
16
|
+
calls := 0
|
|
17
|
+
m := newMock(func(*recordedRequest) (*http.Response, error) {
|
|
18
|
+
calls++
|
|
19
|
+
if calls == 1 {
|
|
20
|
+
return jsonResp(503, map[string]any{}), nil
|
|
21
|
+
}
|
|
22
|
+
return jsonResp(200, map[string]any{}), nil
|
|
23
|
+
})
|
|
24
|
+
c := newClient(t, m, func(cfg *Config) {
|
|
25
|
+
cfg.APIKey = "secret"
|
|
26
|
+
cfg.DefaultHeaders = map[string]string{"X-Team": "default", "authorization": "bad", "content-type": "text/plain", "x-typesafe-retry-count": "99"}
|
|
27
|
+
cfg.Retry = RetryOverrides{MaxRetries: Ptr(1), BackoffInitial: Ptr(time.Duration(0))}
|
|
28
|
+
})
|
|
29
|
+
_, err := c.SystemOne(ctxBG(), SystemOneRequest{State: Text("s"), Questions: Questions{Ask("q", Noul("?"))}}, &RequestOptions{Headers: map[string]string{
|
|
30
|
+
"x-team": "call", "AUTHORIZATION": "bad-again", "ACCEPT": "text/plain", "USER-AGENT": "bad", "X-TYPESAFE-SDK": "bad",
|
|
31
|
+
"X-TYPESAFE-RUNTIME": "bad", "CONTENT-TYPE": "text/html", "X-TYPESAFE-RETRY-COUNT": "88",
|
|
32
|
+
}})
|
|
33
|
+
noErr(t, err)
|
|
34
|
+
eq(t, m.count(), 2)
|
|
35
|
+
for i := 0; i < 2; i++ {
|
|
36
|
+
hd := m.req(i).Header
|
|
37
|
+
eq(t, hd.Get("authorization"), "Bearer secret")
|
|
38
|
+
eq(t, hd.Get("x-team"), "call")
|
|
39
|
+
eq(t, hd.Get("content-type"), "application/json")
|
|
40
|
+
eq(t, hd.Get("accept"), "application/json")
|
|
41
|
+
if !strings.HasPrefix(hd.Get("user-agent"), "typesafe-sdk") || !strings.HasPrefix(hd.Get("x-typesafe-sdk"), "typesafe-sdk") {
|
|
42
|
+
t.Fatalf("identity headers %v", hd)
|
|
43
|
+
}
|
|
44
|
+
if strings.Contains(hd.Get("x-typesafe-runtime"), "bad") {
|
|
45
|
+
t.Fatal("runtime header overridden")
|
|
46
|
+
}
|
|
47
|
+
want := ""
|
|
48
|
+
if i == 1 {
|
|
49
|
+
want = "1"
|
|
50
|
+
}
|
|
51
|
+
eq(t, hd.Get("x-typesafe-retry-count"), want)
|
|
52
|
+
eq(t, len(hd.Values("Authorization")), 1)
|
|
53
|
+
eq(t, len(hd.Values("X-Team")), 1)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
func TestReleaseRegressions_DoesNotSendACallerSuppliedContentTypeOrRetryCountOnGET(t *testing.T) {
|
|
58
|
+
twin(t, "release-regressions.test.ts | release regressions does not send a caller-supplied content type or retry count on GET")
|
|
59
|
+
m := modelsOK()
|
|
60
|
+
c := newClient(t, m, func(cfg *Config) {
|
|
61
|
+
cfg.DefaultHeaders = map[string]string{"content-type": "bad", "x-typesafe-retry-count": "99"}
|
|
62
|
+
})
|
|
63
|
+
_, err := c.Models().List(ctxBG(), nil)
|
|
64
|
+
noErr(t, err)
|
|
65
|
+
hd := m.req(0).Header
|
|
66
|
+
if _, has := hd["Content-Type"]; has {
|
|
67
|
+
t.Fatal("content type on GET")
|
|
68
|
+
}
|
|
69
|
+
if _, has := hd["X-Typesafe-Retry-Count"]; has {
|
|
70
|
+
t.Fatal("retry count on the first attempt")
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
func TestReleaseRegressions_PreservesOwnProtoQuestionsWithoutMutation(t *testing.T) {
|
|
75
|
+
twin(t, "release-regressions.test.ts | release regressions preserves own __proto__ questions without mutation")
|
|
76
|
+
qs := Questions{Ask("__proto__", Noul("?")), Ask("score", Score("?", "no", "yes"))}
|
|
77
|
+
before, err := json.Marshal(qs)
|
|
78
|
+
noErr(t, err)
|
|
79
|
+
m := always(func() *http.Response { return jsonResp(200, map[string]any{}) })
|
|
80
|
+
_, err = newClient(t, m).SystemOne(ctxBG(), SystemOneRequest{State: Text("s"), Questions: qs}, nil)
|
|
81
|
+
noErr(t, err)
|
|
82
|
+
var body struct {
|
|
83
|
+
Questions map[string]json.RawMessage `json:"questions"`
|
|
84
|
+
}
|
|
85
|
+
noErr(t, json.Unmarshal(m.req(0).Raw, &body))
|
|
86
|
+
jsonEq(t, body.Questions["__proto__"], `{"type":"noul","instructions":"?"}`)
|
|
87
|
+
jsonEq(t, body.Questions["score"], `{"type":"score","instructions":"?","criteria":["no","yes"]}`)
|
|
88
|
+
after, err := json.Marshal(qs)
|
|
89
|
+
noErr(t, err)
|
|
90
|
+
eq(t, string(after), string(before))
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
func TestReleaseRegressions_TimesOutAStalledBodyEvenWithACustomFetchIgnoringSignals(t *testing.T) {
|
|
94
|
+
twin(t,
|
|
95
|
+
"release-regressions.test.ts | release regressions times out a stalled 200 body even with a custom fetch ignoring signals",
|
|
96
|
+
"release-regressions.test.ts | release regressions times out a stalled 503 body even with a custom fetch ignoring signals")
|
|
97
|
+
for _, status := range []int{200, 503} {
|
|
98
|
+
synctest.Test(t, func(t *testing.T) {
|
|
99
|
+
var bodies []*blockingBody
|
|
100
|
+
m := newMock(func(*recordedRequest) (*http.Response, error) {
|
|
101
|
+
b := newBlockingBody()
|
|
102
|
+
bodies = append(bodies, b)
|
|
103
|
+
return respWithBody(status, b), nil
|
|
104
|
+
})
|
|
105
|
+
c := newClient(t, m, func(cfg *Config) {
|
|
106
|
+
cfg.Timeout = 50 * time.Millisecond
|
|
107
|
+
cfg.Retry = RetryOverrides{MaxRetries: Ptr(1), BackoffInitial: Ptr(time.Duration(0))}
|
|
108
|
+
})
|
|
109
|
+
_, err := c.Models().List(ctxBG(), nil)
|
|
110
|
+
mustAs[*APITimeoutError](t, err)
|
|
111
|
+
eq(t, m.count(), 2)
|
|
112
|
+
eq(t, len(bodies), 2)
|
|
113
|
+
for _, b := range bodies {
|
|
114
|
+
eq(t, b.closeCount(), 1)
|
|
115
|
+
}
|
|
116
|
+
})
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
func TestReleaseRegressions_WrapsBodyFailuresWithTheirCauseAndHonorsDisabledConnectionRetries(t *testing.T) {
|
|
121
|
+
twin(t,
|
|
122
|
+
"release-regressions.test.ts | release regressions wraps 200 body failures with their cause and honors disabled connection retries",
|
|
123
|
+
"release-regressions.test.ts | release regressions wraps 503 body failures with their cause and honors disabled connection retries")
|
|
124
|
+
for _, status := range []int{200, 503} {
|
|
125
|
+
cause := errors.New("socket dropped")
|
|
126
|
+
m := newMock(func(*recordedRequest) (*http.Response, error) { return respWithBody(status, errBody{cause}), nil })
|
|
127
|
+
c := newClient(t, m, func(cfg *Config) { cfg.Retry = RetryOverrides{APIConnectionError: Ptr(false)} })
|
|
128
|
+
_, err := c.Models().List(ctxBG(), nil)
|
|
129
|
+
conn := mustAs[*APIConnectionError](t, err)
|
|
130
|
+
if !errors.Is(conn, cause) {
|
|
131
|
+
t.Fatalf("%d: cause lost: %v", status, err)
|
|
132
|
+
}
|
|
133
|
+
eq(t, m.count(), 1)
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
func TestReleaseRegressions_CancelsABodyWhenTheSignalWasAbortedJustBeforeFetchReturnedHeaders(t *testing.T) {
|
|
138
|
+
twin(t, "release-regressions.test.ts | release regressions cancels a body when the signal was aborted just before fetch returned headers")
|
|
139
|
+
synctest.Test(t, func(t *testing.T) {
|
|
140
|
+
ctx, cancel := context.WithCancel(context.Background())
|
|
141
|
+
body := newBlockingBody()
|
|
142
|
+
m := newMock(func(*recordedRequest) (*http.Response, error) { cancel(); return respWithBody(200, body), nil })
|
|
143
|
+
_, err := newClient(t, m).Models().List(ctx, nil)
|
|
144
|
+
mustAs[*APIUserAbortError](t, err)
|
|
145
|
+
eq(t, m.count(), 1)
|
|
146
|
+
eq(t, body.closeCount(), 1)
|
|
147
|
+
})
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
func TestReleaseRegressions_ReturnsANullBodyResponseWithoutTryingToReadAStream(t *testing.T) {
|
|
151
|
+
twin(t, "release-regressions.test.ts | release regressions returns a null-body response without trying to read a stream")
|
|
152
|
+
m := newMock(func(*recordedRequest) (*http.Response, error) {
|
|
153
|
+
return &http.Response{StatusCode: 204, Header: http.Header{}, Body: http.NoBody}, nil
|
|
154
|
+
})
|
|
155
|
+
raw, err := newClient(t, m).Models().ListRaw(ctxBG(), nil)
|
|
156
|
+
noErr(t, err)
|
|
157
|
+
eq(t, raw.Status, 204)
|
|
158
|
+
eq(t, len(raw.Body), 0)
|
|
159
|
+
}
|