@desplega.ai/agent-swarm 2.4.5 → 2.5.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 +4 -2
- package/dist/{acp-adapter-2wdkktv6.js → acp-adapter-7g6bpwbk.js} +8 -6
- package/dist/{actions-c40ebcm4.js → actions-w8xd014k.js} +23 -21
- package/dist/{amp-adapter-wb67m95z.js → amp-adapter-z4qvhacj.js} +2 -2
- package/dist/{anthropic-messages-g6pqmqk4.js → anthropic-messages-txs190dd.js} +17 -20
- package/dist/{app-353vre8g.js → app-nndcvftq.js} +3 -3
- package/dist/{assistant-sj1njh23.js → assistant-hjmqyscx.js} +24 -22
- package/dist/{azure-openai-responses-9dbmj346.js → azure-openai-responses-9kfwhmn7.js} +18 -13
- package/dist/{boot-reembed-b9c3az3c.js → boot-reembed-r8rhf9h8.js} +1 -1
- package/dist/{boot-reembed-qdkvxeem.js → boot-reembed-vwcj2y5d.js} +1 -1
- package/dist/{boot-scrub-sweep-m3wh8eks.js → boot-scrub-sweep-fr9q36ne.js} +4 -4
- package/dist/{boot-seeds-j2273s54.js → boot-seeds-9jqwnegq.js} +4 -4
- package/dist/{claude-adapter-m7q0a085.js → claude-adapter-2f8b85df.js} +8 -6
- package/dist/{claude-managed-adapter-5ptb6tzs.js → claude-managed-adapter-gt6pa35d.js} +2 -2
- package/dist/{claude-managed-setup-smrqk5j5.js → claude-managed-setup-c3hp36ph.js} +4 -4
- package/dist/{claude-sdk-session-38xnz21e.js → claude-sdk-session-05kat8rv.js} +9012 -8928
- package/dist/{cli-b9fcxxev.js → cli-007cnhm1.js} +50 -4
- package/dist/{cli-j4rqdf2n.js → cli-03vpq45j.js} +2 -2
- package/dist/{cli-1sp861s4.js → cli-0jy85zz4.js} +11 -11
- package/dist/{cli-j99azg3g.js → cli-1dp1zj04.js} +5 -5
- package/dist/{cli-3r8samv3.js → cli-1f0gp9vz.js} +3 -2
- package/dist/{cli-94gwyg7m.js → cli-22rmcjkg.js} +9 -9
- package/dist/{cli-ms85309d.js → cli-2jg61wab.js} +11 -11
- package/dist/{cli-0bqteszy.js → cli-2nf3b08t.js} +328 -25
- package/dist/{cli-9yqgm9nd.js → cli-2wba1ac9.js} +161 -63
- package/dist/{cli-cxxe61f6.js → cli-3ee5z0q0.js} +2 -2
- package/dist/{cli-k8g16gz3.js → cli-3qv8naq8.js} +115 -119
- package/dist/{cli-60cgh1rv.js → cli-459fk97x.js} +7 -7
- package/dist/{cli-h7gc0b4r.js → cli-5m84zd2k.js} +55 -18
- package/dist/{cli-dvkmp9bt.js → cli-6ctwrf1z.js} +20 -10
- package/dist/{cli-848hxdwj.js → cli-6rg2jn2y.js} +2 -1
- package/dist/{cli-dk44dxec.js → cli-9mm5ade4.js} +1 -1
- package/dist/{cli-7c9qs530.js → cli-ajqhxtnz.js} +5 -5
- package/dist/{cli-be2161h1.js → cli-cah5detr.js} +6 -6
- package/dist/{cli-v8fjakwf.js → cli-cwyafhw1.js} +1 -1
- package/dist/{cli-wxbn3yfx.js → cli-cz5nmdxt.js} +2 -2
- package/dist/{cli-wt645v7q.js → cli-dabehxhp.js} +1 -1
- package/dist/{cli-vfha21c9.js → cli-e5bxnjps.js} +2 -2
- package/dist/{cli-37j04k05.js → cli-e9btqw4y.js} +13 -13
- package/dist/{cli-1syn2xy1.js → cli-eym3jg7w.js} +32 -18
- package/dist/{cli-ftc1g5tj.js → cli-fes51ya2.js} +3 -3
- package/dist/{cli-s95dknxh.js → cli-g1cw7xtt.js} +1 -1
- package/dist/{cli-74c1wpm0.js → cli-gpv60278.js} +1 -1
- package/dist/{cli-1f3qzw6y.js → cli-gwcf52gz.js} +2 -2
- package/dist/{cli-pemywhfq.js → cli-ha9rmwgq.js} +2 -1
- package/dist/{cli-v0yrfmdh.js → cli-hadv0725.js} +3 -3
- package/dist/{cli-g35m2xwm.js → cli-j1eghqfm.js} +2 -2
- package/dist/{cli-qfxc84gh.js → cli-jpxsrxcb.js} +1 -1
- package/dist/{cli-n72rg53p.js → cli-kcsd1ez8.js} +848 -426
- package/dist/{cli-ejs3m1sx.js → cli-kxpfx2xr.js} +1 -1
- package/dist/{cli-pnp2j5zg.js → cli-mmhj8vd7.js} +2 -2
- package/dist/{cli-st8aw1m6.js → cli-mq7kg1b1.js} +4 -4
- package/dist/{cli-bnes4z6b.js → cli-mz2ygeyq.js} +3 -3
- package/dist/{cli-xf234ws8.js → cli-n4c8e3s5.js} +2 -0
- package/dist/{cli-f01h25yt.js → cli-n6kmqngw.js} +2 -2
- package/dist/cli-nj12tn2c.js +1193 -0
- package/dist/{cli-1dmcq2eh.js → cli-nzfnt2gs.js} +1 -1
- package/dist/{cli-625tb7aq.js → cli-p859hcc8.js} +2 -2
- package/dist/{cli-smvcw9z5.js → cli-pasyvjmm.js} +1 -1
- package/dist/cli-pkaqk57w.js +128 -0
- package/dist/{cli-xpa64rek.js → cli-pyy4c9ch.js} +2362 -159
- package/dist/{cli-wt0jf9hm.js → cli-q9pzwxvk.js} +553 -193
- package/dist/{cli-z7d29rw9.js → cli-qfjm4gvt.js} +4 -4
- package/dist/{cli-p14m2cnp.js → cli-qfm6my86.js} +1 -1
- package/dist/{cli-8nyhf7za.js → cli-qqzmjxkf.js} +129 -105
- package/dist/{cli-4zfqgjc5.js → cli-r9fy0ddc.js} +2 -2
- package/dist/{cli-eww120g8.js → cli-rh5smt8t.js} +18 -4
- package/dist/{cli-a92r1127.js → cli-rngde2jv.js} +2 -2
- package/dist/{cli-qwkcwjdn.js → cli-rycdaj0a.js} +1 -1
- package/dist/{cli-fv5hepyy.js → cli-sn1vbtg2.js} +3 -3
- package/dist/{cli-36ckw0wx.js → cli-stxdrqs2.js} +2 -2
- package/dist/{cli-1m17dc9d.js → cli-ta8bd7th.js} +2 -2
- package/dist/{cli-43x64hv3.js → cli-v2g93k4v.js} +4 -4
- package/dist/{cli-d2mb5s8a.js → cli-x77gen2p.js} +680 -440
- package/dist/{cli-3a45zcgm.js → cli-xc65x52q.js} +2 -2
- package/dist/{cli-f0g3pgvf.js → cli-xd4eqtr2.js} +2 -2
- package/dist/{cli-018r4jq6.js → cli-y3zyaee5.js} +8 -8
- package/dist/{cli-kpw04va0.js → cli-z2dv25mf.js} +1 -1
- package/dist/{cli-qwhy2qma.js → cli-z63a269p.js} +2 -2
- package/dist/{cli-sm8rses9.js → cli-zfdp01hn.js} +8 -5
- package/dist/{cli-tw4p90jb.js → cli-znvq0k3t.js} +5 -5
- package/dist/cli.js +29 -27
- package/dist/{cloudflare-workers-ai-system-one-ch2wxfcp.js → cloudflare-workers-ai-system-one-43v9qkjk.js} +7 -2
- package/dist/{codex-adapter-tn6k5mkg.js → codex-adapter-p4ptwar5.js} +6 -4
- package/dist/{codex-login-m819c41r.js → codex-login-rn7c5gxt.js} +1 -1
- package/dist/{codex-session-runner-7vjt7jbw.js → codex-session-runner-964c7dnk.js} +7 -5
- package/dist/{commands-t7rz9146.js → commands-mbvhbrcy.js} +2 -2
- package/dist/{controller-m2jasma5.js → controller-gnq1k1mf.js} +4 -4
- package/dist/{controllers-connect-9ftpex99.js → controllers-connect-6dkm71tg.js} +25 -23
- package/dist/{cursor-adapter-mjv79e4z.js → cursor-adapter-yq5xgfcg.js} +1 -1
- package/dist/{db-6sfrn9g3.js → db-88wcymxt.js} +14 -2
- package/dist/{db-rn673r06.js → db-af9y8nkf.js} +3 -3
- package/dist/{devin-adapter-zgqadvnm.js → devin-adapter-4ycy4vrf.js} +1 -1
- package/dist/{dispatcher-c155xz0p.js → dispatcher-606ydx5v.js} +22 -20
- package/dist/{docker-fkgtr75t.js → docker-nfy2gc8t.js} +2 -2
- package/dist/{dsh-adapter-3mmszc1x.js → dsh-adapter-tvhc4k2d.js} +1 -1
- package/dist/{e2b-16d6ch39.js → e2b-9gkdhm3c.js} +2 -2
- package/dist/{e2b-zn0b4w5w.js → e2b-cjtf8k1z.js} +2 -2
- package/dist/{easter-egg-3d-5cgynaja.js → easter-egg-3d-e4qv8dxj.js} +1 -1
- package/dist/{event-bus-9vpk8gmq.js → event-bus-3z78ep5n.js} +1 -1
- package/dist/{execute-t4e6m3rw.js → execute-0xpz8950.js} +85 -23
- package/dist/{external-channel-35k6tkv8.js → external-channel-y8q5z8z2.js} +2 -2
- package/dist/{google-generative-ai-bmq8gkf3.js → google-generative-ai-mk9vcpe1.js} +15 -15
- package/dist/{google-vertex-b1rvp52s.js → google-vertex-q580kz8k.js} +20 -20
- package/dist/{grok-adapter-tfrq7tg1.js → grok-adapter-39aha52t.js} +9 -7
- package/dist/handlers-rk9dqech.js +41 -0
- package/dist/{heartbeat-dyg4npkp.js → heartbeat-jfe9zfjr.js} +25 -23
- package/dist/{hook-drspbwpe.js → hook-b1mez1m8.js} +9 -7
- package/dist/{hook-x26b31bg.js → hook-ffevzed1.js} +7 -5
- package/dist/{http-pk972xyw.js → http-d5b44f1r.js} +544 -76
- package/dist/{index-g6tbb6ve.js → index-31ceyf42.js} +1 -1
- package/dist/index-4q3vj1yr.js +46 -0
- package/dist/{index-arytgj5q.js → index-5en23s5z.js} +1 -1
- package/dist/index-d2qeem97.js +42 -0
- package/dist/index-mj46rk9k.js +43 -0
- package/dist/{index-jwxkkex2.js → index-nq8hhv28.js} +13 -11
- package/dist/{index-g216q6jr.js → index-zsyx51ap.js} +1 -4
- package/dist/{keepalive-7yrng7px.js → keepalive-wsby1btq.js} +4 -4
- package/dist/lead-paa141j6.js +79 -0
- package/dist/{llama-cpp-classify-vv43gswy.js → llama-cpp-classify-ee7vmd7q.js} +4 -1
- package/dist/{maintenance-e6cemdqt.js → maintenance-vnshcyv9.js} +1 -1
- package/dist/{mistral-conversations-1medfwv7.js → mistral-conversations-sd0xf1tn.js} +13 -13
- package/dist/{node-de6akczr.js → node-jzjj7r9x.js} +1 -1
- package/dist/{oauth-refresh-sweep-yw3xdbcj.js → oauth-refresh-sweep-d6sqn5np.js} +3 -3
- package/dist/{onboard-0a9y5yrc.js → onboard-nr4xhpzy.js} +2 -2
- package/dist/{openai-codex-responses-de9pvs4d.js → openai-codex-responses-79s8xnbh.js} +29 -23
- package/dist/{openai-completions-mtqge3nf.js → openai-completions-tdbyts0x.js} +21 -20
- package/dist/{openai-decisions-ygk4kkxd.js → openai-decisions-bqhnjyfz.js} +2 -1
- package/dist/{openai-responses-dkyng71g.js → openai-responses-dm3t5vqp.js} +26 -17
- package/dist/{opencode-adapter-x4tqzhkh.js → opencode-adapter-e56086m1.js} +7 -5
- package/dist/{openrouter-images-wvv7camj.js → openrouter-images-ssttr1y4.js} +6 -3
- package/dist/{otel-impl-trjpkfb7.js → otel-impl-ytn9wyv9.js} +2 -2
- package/dist/{pi-messages-nhh1pkz2.js → pi-messages-3nf8bq1a.js} +6 -4
- package/dist/{pi-mono-adapter-mcfkn9vf.js → pi-mono-adapter-tzps8f38.js} +9 -37
- package/dist/{pricing-refresh-d2b5my0y.js → pricing-refresh-pva04zee.js} +3 -3
- package/dist/{rbac-roles-nxh5ahwk.js → rbac-roles-7rc1q3g4.js} +1 -1
- package/dist/{rbac-roles-hey3yv9d.js → rbac-roles-ff1ffmec.js} +2 -2
- package/dist/{render-v2-rr3p2atg.js → render-v2-pyfsg9zk.js} +3 -3
- package/dist/{resume-2efkf1s1.js → resume-phj8xhqr.js} +10 -8
- package/dist/{runtime-xe3aqy4x.js → runtime-bt5pkpm1.js} +1 -1
- package/dist/{session-access-s2mttxpw.js → session-access-jzx2z9h5.js} +6 -4
- package/dist/{setup-vypma5yt.js → setup-rfg0f0sg.js} +1 -1
- package/dist/{typesafe-system-one-2hgpayzy.js → typesafe-system-one-bre38hvs.js} +4 -2
- package/dist/{virtual-modules-4r3zkc20.js → virtual-modules-mnfbh5mr.js} +8 -2
- package/dist/{work-objects-rvhckdkp.js → work-objects-44z2yjg8.js} +25 -23
- package/dist/worker-zsfqzxhm.js +79 -0
- package/dist/{x-y45mthwn.js → x-pbpezr0s.js} +2 -2
- package/openapi.json +785 -5
- package/package.json +9 -9
- package/src/assets/key.ts +17 -0
- package/src/azure-devops/handlers.ts +1 -1
- package/src/be/db/approvals.ts +18 -0
- package/src/be/db/session-moves.ts +164 -0
- package/src/be/db/session-tree.ts +384 -0
- package/src/be/db/tasks/read.ts +40 -4
- package/src/be/db/workflow-runs.ts +96 -0
- package/src/be/db.ts +80 -236
- package/src/be/onboarding.ts +3 -0
- package/src/be/skill-sync.ts +43 -2
- package/src/be/swarm-config-guard.ts +1 -0
- package/src/bitbucket/api.ts +81 -0
- package/src/bitbucket/auth.ts +64 -0
- package/src/bitbucket/handlers.ts +434 -0
- package/src/bitbucket/index.ts +28 -0
- package/src/bitbucket/templates.ts +134 -0
- package/src/bitbucket/types.ts +65 -0
- package/src/commands/runner.ts +55 -3
- package/src/e2b/env.ts +1 -0
- package/src/extensions/contract-types.generated.ts +1 -1
- package/src/extensions/contract.ts +2 -2
- package/src/extensions/post-bridge.ts +1 -0
- package/src/github/handlers.ts +6 -6
- package/src/gitlab/auth.ts +8 -2
- package/src/gitlab/handlers.ts +63 -15
- package/src/gitlab/index.ts +1 -1
- package/src/http/assets.ts +14 -2
- package/src/http/core.ts +12 -0
- package/src/http/index.ts +4 -0
- package/src/http/onboarding.ts +1 -0
- package/src/http/sessions.ts +366 -12
- package/src/http/skills.ts +48 -1
- package/src/http/tasks.ts +1 -1
- package/src/http/users.ts +1 -0
- package/src/http/webhooks.ts +141 -0
- package/src/integrations/chat-sdk/adapters.ts +19 -3
- package/src/integrations/chat-sdk/facts.ts +30 -12
- package/src/integrations/chat-sdk/outbound.ts +38 -1
- package/src/providers/acp-targets.ts +1 -1
- package/src/providers/amp-adapter.ts +1 -1
- package/src/providers/pi-mono-adapter.ts +5 -53
- package/src/scripts-runtime/types/swarm-extension.d.ts +6 -4
- package/src/slack/handlers.test.ts +158 -0
- package/src/slack/handlers.ts +19 -28
- package/src/tasks/context-key.ts +61 -1
- package/src/tests/bitbucket-auth.test.ts +156 -0
- package/src/tests/bitbucket-handlers.test.ts +425 -0
- package/src/tests/bitbucket-webhook.test.ts +220 -0
- package/src/tests/chat-sdk-inbound.test.ts +39 -0
- package/src/tests/chat-sdk-telegram-markdown.test.ts +92 -0
- package/src/tests/context-key.test.ts +50 -0
- package/src/tests/core-auth.test.ts +5 -0
- package/src/tests/db-task-read-contract.test.ts +7 -0
- package/src/tests/db-task-write-contract.test.ts +6 -0
- package/src/tests/docs-index-footprint.test.js +3 -3
- package/src/tests/fixtures/bitbucket/pullrequest-comment-created-inline.json +174 -0
- package/src/tests/fixtures/bitbucket/pullrequest-comment-created.json +170 -0
- package/src/tests/fixtures/bitbucket/pullrequest-created-mention.json +132 -0
- package/src/tests/fixtures/bitbucket/pullrequest-created-reviewer.json +140 -0
- package/src/tests/fixtures/bitbucket/pullrequest-fulfilled.json +134 -0
- package/src/tests/fixtures/bitbucket/pullrequest-rejected.json +133 -0
- package/src/tests/generate-mcp-docs.test.ts +101 -0
- package/src/tests/gitlab-auth.test.ts +13 -5
- package/src/tests/gitlab-handlers.test.ts +273 -25
- package/src/tests/gitlab-vcs-db.test.ts +4 -4
- package/src/tests/integration-disable-flags.test.ts +36 -0
- package/src/tests/mcp-tools.test.ts +1 -1
- package/src/tests/onboarding.test.ts +12 -0
- package/src/tests/pi-codemode.test.ts +8 -2
- package/src/tests/preload-env.test.ts +57 -0
- package/src/tests/preload.ts +21 -0
- package/src/tests/prompt-template-remaining.test.ts +38 -0
- package/src/tests/run-root-coverage.test.ts +39 -0
- package/src/tests/runner-bitbucket-vcs.test.ts +191 -0
- package/src/tests/runner-skills-refresh.test.ts +58 -0
- package/src/tests/secret-scrubber.test.ts +15 -0
- package/src/tests/sessions-move.test.ts +576 -0
- package/src/tests/sessions-tree.test.ts +493 -0
- package/src/tests/skill-files-http.test.ts +50 -0
- package/src/tests/skills-bundle.test.ts +99 -0
- package/src/tests/swarm-config-export-to-env.test.ts +2 -1
- package/src/tests/vcs-bitbucket.test.ts +91 -0
- package/src/tests/vcs-provider-isolation.test.ts +123 -0
- package/src/tests/vcs-provider.test.ts +16 -1
- package/src/tests/vcs-tracking.test.ts +3 -3
- package/src/tests/workflow-foreach-bodies.test.ts +637 -0
- package/src/tests/workflow-foreach-concurrency.test.ts +342 -0
- package/src/tests/workflow-foreach-retry.test.ts +537 -0
- package/src/tests/workflow-foreach.test.ts +44 -23
- package/src/tests/workflow-step-claims.test.ts +6 -6
- package/src/tests/workflow-tla-races.test.ts +2 -2
- package/src/tools/script-delete.ts +1 -1
- package/src/tools/workflows/create-workflow.ts +5 -3
- package/src/types.ts +3 -2
- package/src/utils/config-env-export.ts +1 -0
- package/src/utils/secret-scrubber.ts +4 -0
- package/src/utils/skills-refresh.ts +83 -43
- package/src/vcs/bitbucket.ts +58 -0
- package/src/vcs/index.ts +2 -0
- package/src/vcs/types.ts +2 -2
- package/src/workflows/approval-resolution.ts +4 -1
- package/src/workflows/checkpoint.ts +9 -1
- package/src/workflows/constants.ts +3 -0
- package/src/workflows/definition.ts +48 -17
- package/src/workflows/engine.ts +25 -15
- package/src/workflows/executors/foreach.ts +45 -99
- package/src/workflows/foreach-body.ts +146 -0
- package/src/workflows/foreach-driver.ts +552 -0
- package/src/workflows/foreach-join.ts +206 -7
- package/src/workflows/node-timeout.ts +21 -0
- package/src/workflows/recovery.ts +68 -3
- package/src/workflows/resume.ts +221 -43
- package/src/workflows/retry-poller.ts +39 -24
- package/src/workflows/step-input.ts +59 -0
- package/src/workflows/task-step-routing.ts +114 -56
- package/templates/skills/slack-interaction/content.md +5 -0
- package/templates/skills/work-on-task/SKILL.md +1 -1
- package/templates/skills/work-on-task/content.md +1 -1
- package/dist/cli-9hstj09h.js +0 -2657
- package/dist/cli-yw91rnmw.js +0 -13
- package/dist/handlers-7gw64dxw.js +0 -39
- package/dist/index-bgdyvcnv.js +0 -40
- package/dist/index-gabbcdn2.js +0 -43
- package/dist/index-tfb26zhy.js +0 -41
- package/dist/lead-7e02z839.js +0 -77
- package/dist/worker-5snytpbd.js +0 -77
|
@@ -2,6 +2,29 @@ import {
|
|
|
2
2
|
AssistantMessageEventStream,
|
|
3
3
|
formatThrownValue
|
|
4
4
|
} from "./cli-m6m1bvtp.js";
|
|
5
|
+
import {
|
|
6
|
+
mergeClientIdentity,
|
|
7
|
+
getOpenCodeSessionHeaders
|
|
8
|
+
} from "./cli-pkaqk57w.js";
|
|
9
|
+
import {
|
|
10
|
+
__export
|
|
11
|
+
} from "./cli-242037k3.js";
|
|
12
|
+
|
|
13
|
+
// node_modules/@earendil-works/pi-ai/dist/models.js
|
|
14
|
+
var exports_models = {};
|
|
15
|
+
__export(exports_models, {
|
|
16
|
+
AI_TELEMETRY_SCHEMA: () => AI_TELEMETRY_SCHEMA,
|
|
17
|
+
ModelsError: () => ModelsError,
|
|
18
|
+
calculateCost: () => calculateCost,
|
|
19
|
+
clampThinkingLevel: () => clampThinkingLevel,
|
|
20
|
+
createModels: () => createModels,
|
|
21
|
+
createProvider: () => createProvider,
|
|
22
|
+
getModelType: () => getModelType,
|
|
23
|
+
getSupportedThinkingLevels: () => getSupportedThinkingLevels,
|
|
24
|
+
hasApi: () => hasApi,
|
|
25
|
+
isModelType: () => isModelType,
|
|
26
|
+
modelsAreEqual: () => modelsAreEqual
|
|
27
|
+
});
|
|
5
28
|
|
|
6
29
|
// node_modules/@earendil-works/pi-ai/dist/api/lazy.js
|
|
7
30
|
function createSetupErrorMessage(model, error, timestamp) {
|
|
@@ -27,19 +50,38 @@ function createSetupErrorMessage(model, error, timestamp) {
|
|
|
27
50
|
function hasResult(source) {
|
|
28
51
|
return typeof source.result === "function";
|
|
29
52
|
}
|
|
30
|
-
async function forwardStream(target, source) {
|
|
53
|
+
async function forwardStream(target, source, observer, observeResult) {
|
|
54
|
+
let result;
|
|
31
55
|
for await (const event of source) {
|
|
32
56
|
target.push(event);
|
|
33
|
-
|
|
34
|
-
|
|
57
|
+
observer?.onEvent?.(event);
|
|
58
|
+
if (event.type === "done")
|
|
59
|
+
result = event.message;
|
|
60
|
+
else if (event.type === "error")
|
|
61
|
+
result = event.error;
|
|
62
|
+
}
|
|
63
|
+
if (hasResult(source))
|
|
64
|
+
result = await source.result();
|
|
65
|
+
target.end(result);
|
|
66
|
+
observeResult(result);
|
|
35
67
|
}
|
|
36
|
-
function lazyStream(model, setup) {
|
|
68
|
+
function lazyStream(model, setup, observer) {
|
|
37
69
|
const startedAt = Date.now();
|
|
38
70
|
const outer = new AssistantMessageEventStream;
|
|
39
|
-
|
|
71
|
+
let observedResult = false;
|
|
72
|
+
const observeResult = (result) => {
|
|
73
|
+
if (observedResult)
|
|
74
|
+
return;
|
|
75
|
+
observedResult = true;
|
|
76
|
+
observer?.onResult?.(result);
|
|
77
|
+
};
|
|
78
|
+
setup().then((inner) => forwardStream(outer, inner, observer, observeResult)).catch((error) => {
|
|
40
79
|
const message = createSetupErrorMessage(model, error, startedAt);
|
|
41
|
-
|
|
80
|
+
const event = { type: "error", reason: "error", error: message };
|
|
81
|
+
outer.push(event);
|
|
82
|
+
observer?.onEvent?.(event);
|
|
42
83
|
outer.end(message);
|
|
84
|
+
observeResult(message);
|
|
43
85
|
});
|
|
44
86
|
return outer;
|
|
45
87
|
}
|
|
@@ -331,6 +373,251 @@ class InMemoryModelsStore {
|
|
|
331
373
|
}
|
|
332
374
|
}
|
|
333
375
|
|
|
376
|
+
// node_modules/@earendil-works/pi-telemetry/dist/metrics.js
|
|
377
|
+
function createTypedMetrics(metrics, schemas) {
|
|
378
|
+
const definitions = new Map;
|
|
379
|
+
for (const schema of schemas) {
|
|
380
|
+
for (const [name, definition] of Object.entries(schema.metrics ?? {}))
|
|
381
|
+
definitions.set(name, definition);
|
|
382
|
+
}
|
|
383
|
+
return {
|
|
384
|
+
counter: (name) => metrics.counter(name, definitions.get(name)),
|
|
385
|
+
upDownCounter: (name) => metrics.upDownCounter(name, definitions.get(name)),
|
|
386
|
+
histogram: (name) => metrics.histogram(name, definitions.get(name))
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
// node_modules/@earendil-works/pi-telemetry/dist/noop.js
|
|
390
|
+
async function startNoopSpan(_options, callback) {
|
|
391
|
+
return callback(noopTelemetrySpan);
|
|
392
|
+
}
|
|
393
|
+
var noopCounter = Object.freeze({ add: () => {} });
|
|
394
|
+
var noopUpDownCounter = Object.freeze({ add: () => {} });
|
|
395
|
+
var noopHistogram = Object.freeze({ record: () => {} });
|
|
396
|
+
var NOOP_TELEMETRY_METRICS = Object.freeze({
|
|
397
|
+
counter: () => noopCounter,
|
|
398
|
+
upDownCounter: () => noopUpDownCounter,
|
|
399
|
+
histogram: () => noopHistogram
|
|
400
|
+
});
|
|
401
|
+
var NOOP_TELEMETRY_PROPAGATION = Object.freeze({
|
|
402
|
+
inject: () => {
|
|
403
|
+
return;
|
|
404
|
+
},
|
|
405
|
+
extract: () => NOOP_TELEMETRY_CONTEXT
|
|
406
|
+
});
|
|
407
|
+
var noopTelemetrySpan = {
|
|
408
|
+
metrics: NOOP_TELEMETRY_METRICS,
|
|
409
|
+
propagation: NOOP_TELEMETRY_PROPAGATION,
|
|
410
|
+
startSpan: startNoopSpan,
|
|
411
|
+
addLink: () => {},
|
|
412
|
+
addEvent: () => {},
|
|
413
|
+
setAttributes: () => {},
|
|
414
|
+
setStatus: () => {}
|
|
415
|
+
};
|
|
416
|
+
Object.freeze(noopTelemetrySpan);
|
|
417
|
+
var NOOP_TELEMETRY_CONTEXT = noopTelemetrySpan;
|
|
418
|
+
// node_modules/@earendil-works/pi-telemetry/dist/memory.js
|
|
419
|
+
var contextCarriers = new WeakMap;
|
|
420
|
+
|
|
421
|
+
// node_modules/@earendil-works/pi-telemetry/dist/index.js
|
|
422
|
+
function defineTelemetrySchema(schema) {
|
|
423
|
+
return schema;
|
|
424
|
+
}
|
|
425
|
+
function bindTypedSpanStarter(telemetryContext) {
|
|
426
|
+
const startSpan = (name, attributes, callback) => telemetryContext.startSpan({ name, attributes }, (span) => callback(span, bindTypedSpanStarter(span)));
|
|
427
|
+
return startSpan;
|
|
428
|
+
}
|
|
429
|
+
function createTypedSpanStarter(telemetryContext, _schemas) {
|
|
430
|
+
return bindTypedSpanStarter(telemetryContext);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// node_modules/@earendil-works/pi-ai/dist/telemetry.js
|
|
434
|
+
var provider = { type: "string", description: "Provider identifier.", required: true };
|
|
435
|
+
var model = { type: "string", description: "Requested model identifier.", required: true };
|
|
436
|
+
var stop = {
|
|
437
|
+
type: "string",
|
|
438
|
+
description: "Normalized stop reason.",
|
|
439
|
+
values: ["pending", "stop", "length", "toolUse", "error", "aborted", "deferred"]
|
|
440
|
+
};
|
|
441
|
+
var request = {
|
|
442
|
+
description: "One logical model request, including authentication and provider setup.",
|
|
443
|
+
parents: { kind: "any" },
|
|
444
|
+
startAttributes: {
|
|
445
|
+
provider,
|
|
446
|
+
api: { type: "string", description: "API identifier.", required: true },
|
|
447
|
+
model,
|
|
448
|
+
reasoning: { type: "string", description: "Scalar requested reasoning level.", required: false }
|
|
449
|
+
},
|
|
450
|
+
endAttributes: {
|
|
451
|
+
stop,
|
|
452
|
+
"usage.input": { type: "number", description: "Uncached input tokens." },
|
|
453
|
+
"usage.output": { type: "number", description: "Output tokens." },
|
|
454
|
+
"usage.cache_read": { type: "number", description: "Cache-read tokens." },
|
|
455
|
+
"usage.cache_write": { type: "number", description: "Cache-write tokens." },
|
|
456
|
+
"cost.total": { type: "number", description: "Total request cost in USD." },
|
|
457
|
+
"response.id": { type: "string", description: "Provider response identifier.", cardinality: "high" }
|
|
458
|
+
},
|
|
459
|
+
events: {
|
|
460
|
+
"pi.ai.first_chunk": { description: "First normalized stream event delivered.", attributes: {} },
|
|
461
|
+
"pi.ai.block": {
|
|
462
|
+
description: "A completed content block; content is never recorded.",
|
|
463
|
+
attributes: {
|
|
464
|
+
type: {
|
|
465
|
+
type: "string",
|
|
466
|
+
description: "Block kind.",
|
|
467
|
+
values: ["text", "thinking", "tool_call"],
|
|
468
|
+
required: true
|
|
469
|
+
},
|
|
470
|
+
index: { type: "number", description: "Content block index.", required: true },
|
|
471
|
+
chars: { type: "number", description: "UTF-16 character count.", required: true },
|
|
472
|
+
tool: { type: "string", description: "Tool name, for tool-call blocks only.", required: false }
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
},
|
|
476
|
+
status: {
|
|
477
|
+
default: "ok",
|
|
478
|
+
errorWhen: "Stop reason is error: provider_error with at most 500 error-message characters. Aborted stays ok."
|
|
479
|
+
}
|
|
480
|
+
};
|
|
481
|
+
var AI_TELEMETRY_SCHEMA = defineTelemetrySchema({
|
|
482
|
+
version: 1,
|
|
483
|
+
spans: {
|
|
484
|
+
"pi.ai.request": request,
|
|
485
|
+
"pi.ai.poll": { ...request, description: "One deferred-response poll, not the deferred request's lifetime." }
|
|
486
|
+
},
|
|
487
|
+
metrics: {
|
|
488
|
+
"pi.ai.request.duration": {
|
|
489
|
+
kind: "histogram",
|
|
490
|
+
description: "Logical request or poll duration.",
|
|
491
|
+
unit: "ms",
|
|
492
|
+
attributes: { provider, model, stop: { ...stop, required: true } }
|
|
493
|
+
},
|
|
494
|
+
"pi.ai.first_chunk.duration": {
|
|
495
|
+
kind: "histogram",
|
|
496
|
+
description: "Time to the first normalized stream event.",
|
|
497
|
+
unit: "ms",
|
|
498
|
+
attributes: { provider, model }
|
|
499
|
+
},
|
|
500
|
+
"pi.ai.tokens": {
|
|
501
|
+
kind: "counter",
|
|
502
|
+
description: "Reported model token usage; pending and deferred polls are excluded.",
|
|
503
|
+
unit: "token",
|
|
504
|
+
attributes: {
|
|
505
|
+
provider,
|
|
506
|
+
model,
|
|
507
|
+
kind: {
|
|
508
|
+
type: "string",
|
|
509
|
+
description: "Token usage category.",
|
|
510
|
+
values: ["input", "output", "cache_read", "cache_write"],
|
|
511
|
+
required: true
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
},
|
|
515
|
+
"pi.ai.cost": {
|
|
516
|
+
kind: "counter",
|
|
517
|
+
description: "Reported model cost; pending and deferred polls are excluded.",
|
|
518
|
+
unit: "USD",
|
|
519
|
+
attributes: { provider, model }
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
});
|
|
523
|
+
function createInstruments(adapter) {
|
|
524
|
+
const metrics = createTypedMetrics(adapter, [AI_TELEMETRY_SCHEMA]);
|
|
525
|
+
return {
|
|
526
|
+
requestDuration: metrics.histogram("pi.ai.request.duration"),
|
|
527
|
+
firstChunkDuration: metrics.histogram("pi.ai.first_chunk.duration"),
|
|
528
|
+
tokens: metrics.counter("pi.ai.tokens"),
|
|
529
|
+
cost: metrics.counter("pi.ai.cost")
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
var instrumentCache = new WeakMap;
|
|
533
|
+
function observeModelRequest(requestedModel, options, poll) {
|
|
534
|
+
const started = performance.now();
|
|
535
|
+
const attributes = { provider: requestedModel.provider, model: requestedModel.id };
|
|
536
|
+
const adapter = options?.telemetry?.metrics ?? NOOP_TELEMETRY_METRICS;
|
|
537
|
+
let instruments = instrumentCache.get(adapter);
|
|
538
|
+
if (!instruments) {
|
|
539
|
+
instruments = createInstruments(adapter);
|
|
540
|
+
instrumentCache.set(adapter, instruments);
|
|
541
|
+
}
|
|
542
|
+
const { requestDuration, firstChunkDuration, tokens, cost } = instruments;
|
|
543
|
+
let span;
|
|
544
|
+
let finish;
|
|
545
|
+
let first = true;
|
|
546
|
+
const toolChars = new Map;
|
|
547
|
+
const finished = new Promise((resolve) => {
|
|
548
|
+
finish = resolve;
|
|
549
|
+
});
|
|
550
|
+
const run = (activeSpan) => {
|
|
551
|
+
span = activeSpan;
|
|
552
|
+
return finished;
|
|
553
|
+
};
|
|
554
|
+
const startAttributes = {
|
|
555
|
+
...attributes,
|
|
556
|
+
api: requestedModel.api,
|
|
557
|
+
...typeof options?.reasoning === "string" ? { reasoning: options.reasoning } : {}
|
|
558
|
+
};
|
|
559
|
+
const start = createTypedSpanStarter(options?.telemetry ?? NOOP_TELEMETRY_CONTEXT, [AI_TELEMETRY_SCHEMA]);
|
|
560
|
+
if (poll)
|
|
561
|
+
start("pi.ai.poll", startAttributes, run);
|
|
562
|
+
else
|
|
563
|
+
start("pi.ai.request", startAttributes, run);
|
|
564
|
+
return {
|
|
565
|
+
onEvent(event) {
|
|
566
|
+
if (first) {
|
|
567
|
+
first = false;
|
|
568
|
+
span.addEvent("pi.ai.first_chunk");
|
|
569
|
+
firstChunkDuration.record(performance.now() - started, attributes, span);
|
|
570
|
+
}
|
|
571
|
+
if (event.type === "toolcall_delta") {
|
|
572
|
+
toolChars.set(event.contentIndex, (toolChars.get(event.contentIndex) ?? 0) + event.delta.length);
|
|
573
|
+
} else if (event.type === "text_end" || event.type === "thinking_end") {
|
|
574
|
+
span.addEvent("pi.ai.block", {
|
|
575
|
+
type: event.type === "text_end" ? "text" : "thinking",
|
|
576
|
+
index: event.contentIndex,
|
|
577
|
+
chars: event.content.length
|
|
578
|
+
});
|
|
579
|
+
} else if (event.type === "toolcall_end") {
|
|
580
|
+
const chars = toolChars.get(event.contentIndex) ?? 0;
|
|
581
|
+
toolChars.delete(event.contentIndex);
|
|
582
|
+
span.addEvent("pi.ai.block", {
|
|
583
|
+
type: "tool_call",
|
|
584
|
+
index: event.contentIndex,
|
|
585
|
+
chars,
|
|
586
|
+
tool: event.toolCall.name
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
},
|
|
590
|
+
onResult(message) {
|
|
591
|
+
if (message) {
|
|
592
|
+
span.setAttributes({
|
|
593
|
+
stop: message.stopReason,
|
|
594
|
+
"usage.input": message.usage.input,
|
|
595
|
+
"usage.output": message.usage.output,
|
|
596
|
+
"usage.cache_read": message.usage.cacheRead,
|
|
597
|
+
"usage.cache_write": message.usage.cacheWrite,
|
|
598
|
+
"cost.total": message.usage.cost.total,
|
|
599
|
+
"response.id": message.responseId
|
|
600
|
+
});
|
|
601
|
+
if (message.stopReason === "error") {
|
|
602
|
+
span.setStatus({
|
|
603
|
+
status: "error",
|
|
604
|
+
error: { name: "provider_error", message: message.errorMessage?.slice(0, 500) ?? "" }
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
requestDuration.record(performance.now() - started, { ...attributes, stop: message.stopReason }, span);
|
|
608
|
+
if (!poll || message.stopReason !== "pending" && message.stopReason !== "deferred") {
|
|
609
|
+
tokens.add(message.usage.input, { ...attributes, kind: "input" });
|
|
610
|
+
tokens.add(message.usage.output, { ...attributes, kind: "output" });
|
|
611
|
+
tokens.add(message.usage.cacheRead, { ...attributes, kind: "cache_read" });
|
|
612
|
+
tokens.add(message.usage.cacheWrite, { ...attributes, kind: "cache_write" });
|
|
613
|
+
cost.add(message.usage.cost.total, attributes);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
finish();
|
|
617
|
+
}
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
|
|
334
621
|
// node_modules/@earendil-works/pi-ai/dist/utils/model-operations.js
|
|
335
622
|
function getModelType(model) {
|
|
336
623
|
return model.type ?? "chat";
|
|
@@ -546,26 +833,32 @@ function hasToolRedefinitions(messages) {
|
|
|
546
833
|
return false;
|
|
547
834
|
}
|
|
548
835
|
function hasNonAdditiveToolChanges(messages) {
|
|
836
|
+
return findLastNonAdditiveToolChange(messages.filter(isSystemMessage)) >= 0;
|
|
837
|
+
}
|
|
838
|
+
function findLastNonAdditiveToolChange(systemMessages) {
|
|
549
839
|
const declared = new Set;
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
840
|
+
let last = -1;
|
|
841
|
+
for (let index = 0;index < systemMessages.length; index++) {
|
|
842
|
+
const message = systemMessages[index];
|
|
553
843
|
if ((message.toolsRemoved?.length ?? 0) > 0)
|
|
554
|
-
|
|
844
|
+
last = index;
|
|
555
845
|
for (const tool of message.toolsAdded ?? []) {
|
|
556
846
|
if (declared.has(tool.name))
|
|
557
|
-
|
|
847
|
+
last = index;
|
|
558
848
|
declared.add(tool.name);
|
|
559
849
|
}
|
|
560
850
|
}
|
|
561
|
-
return
|
|
851
|
+
return last;
|
|
562
852
|
}
|
|
563
|
-
function resolveTranscriptTools(messages,
|
|
564
|
-
const
|
|
565
|
-
|
|
566
|
-
requestTools:
|
|
567
|
-
|
|
568
|
-
|
|
853
|
+
function resolveTranscriptTools(messages, support) {
|
|
854
|
+
const systemMessages = messages.filter(isSystemMessage);
|
|
855
|
+
if (support === "none") {
|
|
856
|
+
return { requestTools: getCurrentTools(systemMessages), foldedSystemMessages: systemMessages.length };
|
|
857
|
+
}
|
|
858
|
+
if (support === "changes")
|
|
859
|
+
return { requestTools: [], foldedSystemMessages: 0 };
|
|
860
|
+
const folded = Math.max(getInitialSystemMessage(messages) ? 1 : 0, findLastNonAdditiveToolChange(systemMessages) + 1);
|
|
861
|
+
return { requestTools: getCurrentTools(systemMessages.slice(0, folded)), foldedSystemMessages: folded };
|
|
569
862
|
}
|
|
570
863
|
|
|
571
864
|
// node_modules/@earendil-works/pi-ai/dist/models.js
|
|
@@ -596,6 +889,7 @@ class ModelsImpl {
|
|
|
596
889
|
credentials;
|
|
597
890
|
modelsStore;
|
|
598
891
|
authContext;
|
|
892
|
+
identity;
|
|
599
893
|
refreshGenerations = new Map;
|
|
600
894
|
refreshControllers = new Map;
|
|
601
895
|
publicationChains = new Map;
|
|
@@ -603,6 +897,7 @@ class ModelsImpl {
|
|
|
603
897
|
this.credentials = options?.credentials ?? new InMemoryCredentialStore;
|
|
604
898
|
this.modelsStore = options?.modelsStore ?? new InMemoryModelsStore;
|
|
605
899
|
this.authContext = options?.authContext ?? defaultProviderAuthContext();
|
|
900
|
+
this.identity = options?.identity;
|
|
606
901
|
}
|
|
607
902
|
setProvider(provider) {
|
|
608
903
|
this.supersedeProviderRefresh(provider.id);
|
|
@@ -967,13 +1262,21 @@ class ModelsImpl {
|
|
|
967
1262
|
}
|
|
968
1263
|
const auth = resolution.auth;
|
|
969
1264
|
const apiKey = options?.apiKey ?? auth.apiKey;
|
|
970
|
-
|
|
1265
|
+
const requestModel = auth.baseUrl ? { ...model, baseUrl: auth.baseUrl } : model;
|
|
1266
|
+
const sessionId = options && "sessionId" in options && typeof options.sessionId === "string" ? options.sessionId : undefined;
|
|
1267
|
+
let headers = mergeHeaders(mergeHeaders(getOpenCodeSessionHeaders(requestModel, sessionId), auth.headers), options?.headers);
|
|
971
1268
|
if (options?.transformHeaders)
|
|
972
1269
|
headers = await options.transformHeaders(headers ?? {});
|
|
973
1270
|
const env = resolution.env || options?.env ? { ...resolution.env ?? {}, ...options?.env ?? {} } : undefined;
|
|
974
|
-
const
|
|
1271
|
+
const identity = mergeClientIdentity(this.identity, options?.identity);
|
|
975
1272
|
const { transformHeaders: _transformHeaders, ...providerOptions } = options ?? {};
|
|
976
|
-
const requestOptions = {
|
|
1273
|
+
const requestOptions = {
|
|
1274
|
+
...providerOptions,
|
|
1275
|
+
apiKey,
|
|
1276
|
+
headers,
|
|
1277
|
+
env,
|
|
1278
|
+
...identity === undefined ? {} : { identity }
|
|
1279
|
+
};
|
|
977
1280
|
return { requestModel, requestOptions };
|
|
978
1281
|
}
|
|
979
1282
|
stream(model, context, options) {
|
|
@@ -982,7 +1285,7 @@ class ModelsImpl {
|
|
|
982
1285
|
const provider = this.requireChatProvider(model);
|
|
983
1286
|
const { requestModel, requestOptions } = await this.applyAuth(model, options);
|
|
984
1287
|
return provider.stream(requestModel, transcript, requestOptions);
|
|
985
|
-
});
|
|
1288
|
+
}, observeModelRequest(model, options, false));
|
|
986
1289
|
}
|
|
987
1290
|
async complete(model, context, options) {
|
|
988
1291
|
return this.stream(model, context, options).result();
|
|
@@ -993,7 +1296,7 @@ class ModelsImpl {
|
|
|
993
1296
|
const provider = this.requireChatProvider(model);
|
|
994
1297
|
const { requestModel, requestOptions } = await this.applyAuth(model, options);
|
|
995
1298
|
return provider.streamSimple(requestModel, transcript, requestOptions);
|
|
996
|
-
});
|
|
1299
|
+
}, observeModelRequest(model, options, false));
|
|
997
1300
|
}
|
|
998
1301
|
async completeSimple(model, context, options) {
|
|
999
1302
|
return this.streamSimple(model, context, options).result();
|
|
@@ -1006,7 +1309,7 @@ class ModelsImpl {
|
|
|
1006
1309
|
}
|
|
1007
1310
|
const { requestModel, requestOptions } = await this.applyAuth(model, options);
|
|
1008
1311
|
return provider.fetchDeferred(requestModel, handle, requestOptions);
|
|
1009
|
-
});
|
|
1312
|
+
}, observeModelRequest(model, options, true));
|
|
1010
1313
|
}
|
|
1011
1314
|
async fetchDeferred(model, handle, options) {
|
|
1012
1315
|
return this.streamDeferred(model, handle, options).result();
|
|
@@ -1220,4 +1523,4 @@ function modelsAreEqual(a, b) {
|
|
|
1220
1523
|
return getModelType(a) === getModelType(b) && a.id === b.id && a.provider === b.provider;
|
|
1221
1524
|
}
|
|
1222
1525
|
|
|
1223
|
-
export { lazyStream, lazyApi, defaultProviderAuthContext, InMemoryCredentialStore, ModelsError, InMemoryModelsStore, getModelType, isModelType, assertChatModel, assertImageModel, assertClassifierModel, assertClassifierInputSupported, imageErrorResult, classifierErrorResult, contentText, getSystemMessageText, renderSystemMessageUpdate, createInitialSystemMessage, normalizeContext, getInitialSystemMessage, withoutInitialSystemMessage, getCurrentTools, getCurrentSystemMessage, getCurrentSystemPrompt, collapseSystemMessages, resolveTranscript, toToolDeclaration, declarationsEqual, getToolStateChanges, getDeclaredTools, hasToolRedefinitions, hasNonAdditiveToolChanges, resolveTranscriptTools, createModels, createProvider, hasApi, calculateCost, getSupportedThinkingLevels, clampThinkingLevel, modelsAreEqual };
|
|
1526
|
+
export { lazyStream, lazyApi, defaultProviderAuthContext, InMemoryCredentialStore, ModelsError, InMemoryModelsStore, AI_TELEMETRY_SCHEMA, getModelType, isModelType, assertChatModel, assertImageModel, assertClassifierModel, assertClassifierInputSupported, imageErrorResult, classifierErrorResult, contentText, getSystemMessageText, renderSystemMessageUpdate, createInitialSystemMessage, normalizeContext, getInitialSystemMessage, withoutInitialSystemMessage, getCurrentTools, getCurrentSystemMessage, getCurrentSystemPrompt, collapseSystemMessages, resolveTranscript, toToolDeclaration, declarationsEqual, getToolStateChanges, getDeclaredTools, hasToolRedefinitions, hasNonAdditiveToolChanges, resolveTranscriptTools, createModels, createProvider, hasApi, calculateCost, getSupportedThinkingLevels, clampThinkingLevel, modelsAreEqual, exports_models };
|