gemi 0.110.0 → 0.112.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/dist/ai/Agent.d.ts +65 -1
- package/dist/ai/Agent.d.ts.map +1 -1
- package/dist/ai/AgentController.d.ts +48 -0
- package/dist/ai/AgentController.d.ts.map +1 -1
- package/dist/ai/client/index.d.ts +1 -1
- package/dist/ai/client/index.d.ts.map +1 -1
- package/dist/ai/contextCompaction.d.ts +247 -0
- package/dist/ai/contextCompaction.d.ts.map +1 -0
- package/dist/ai/contextWindow.d.ts +18 -0
- package/dist/ai/contextWindow.d.ts.map +1 -1
- package/dist/ai/index.d.ts +5 -1
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +93 -14
- package/dist/ai/index.js.map +16 -10
- package/dist/ai/jobs/AgentJob.d.ts +259 -0
- package/dist/ai/jobs/AgentJob.d.ts.map +1 -0
- package/dist/ai/jobs/AgentJobDeadlineSweep.d.ts +18 -0
- package/dist/ai/jobs/AgentJobDeadlineSweep.d.ts.map +1 -0
- package/dist/ai/jobs/AgentJobStore.d.ts +141 -0
- package/dist/ai/jobs/AgentJobStore.d.ts.map +1 -0
- package/dist/ai/jobs/DatabaseAgentJobStore.d.ts +82 -0
- package/dist/ai/jobs/DatabaseAgentJobStore.d.ts.map +1 -0
- package/dist/ai/jobs/contextBlock.d.ts +31 -0
- package/dist/ai/jobs/contextBlock.d.ts.map +1 -0
- package/dist/ai/jobs/index.d.ts +6 -0
- package/dist/ai/jobs/index.d.ts.map +1 -0
- package/dist/ai/jobs/overlay.d.ts +49 -0
- package/dist/ai/jobs/overlay.d.ts.map +1 -0
- package/dist/ai/providers/request.d.ts.map +1 -1
- package/dist/ai/store/Attachments.d.ts +6 -0
- package/dist/ai/store/Attachments.d.ts.map +1 -1
- package/dist/ai/store/MemoryAgentStore.d.ts +3 -0
- package/dist/ai/store/MemoryAgentStore.d.ts.map +1 -1
- package/dist/ai/types.d.ts +28 -0
- package/dist/ai/types.d.ts.map +1 -1
- package/dist/app/index.js +1 -1
- package/dist/bin/gemi.js +13 -2
- package/dist/bin/gemi.js.map +4 -4
- package/dist/bun/plugin.js +1 -1
- package/dist/bun/preload.js +1 -1
- package/dist/{chunk-30xjcyzh.js → chunk-0z2h35d7.js} +2 -2
- package/dist/{chunk-30xjcyzh.js.map → chunk-0z2h35d7.js.map} +1 -1
- package/dist/{chunk-358sdcx9.js → chunk-15a1mrdv.js} +2 -2
- package/dist/{chunk-358sdcx9.js.map → chunk-15a1mrdv.js.map} +1 -1
- package/dist/{chunk-hf7a51s3.js → chunk-18c3y8m3.js} +2 -2
- package/dist/{chunk-hf7a51s3.js.map → chunk-18c3y8m3.js.map} +1 -1
- package/dist/{chunk-tq85n8zh.js → chunk-1pvkw2pq.js} +2 -2
- package/dist/{chunk-tq85n8zh.js.map → chunk-1pvkw2pq.js.map} +1 -1
- package/dist/{chunk-8afxrmdc.js → chunk-2taa0brj.js} +2 -2
- package/dist/{chunk-8afxrmdc.js.map → chunk-2taa0brj.js.map} +1 -1
- package/dist/{chunk-5cygrbxv.js → chunk-30yg31sz.js} +2 -2
- package/dist/{chunk-5cygrbxv.js.map → chunk-30yg31sz.js.map} +1 -1
- package/dist/{chunk-3y8q8x11.js → chunk-3z9vhjd7.js} +2 -2
- package/dist/{chunk-3y8q8x11.js.map → chunk-3z9vhjd7.js.map} +1 -1
- package/dist/chunk-4sb1484x.js +46 -0
- package/dist/{chunk-h3864a8z.js.map → chunk-4sb1484x.js.map} +13 -4
- package/dist/{chunk-0sjh5v1n.js → chunk-53bek7sp.js} +1 -1
- package/dist/{chunk-xkc7ftnq.js → chunk-57edag57.js} +3 -3
- package/dist/{chunk-xkc7ftnq.js.map → chunk-57edag57.js.map} +1 -1
- package/dist/{chunk-ddr4qvvt.js → chunk-5az0mq4p.js} +3 -3
- package/dist/{chunk-ddr4qvvt.js.map → chunk-5az0mq4p.js.map} +1 -1
- package/dist/{chunk-nsvktvp4.js → chunk-5waxjsvv.js} +2 -2
- package/dist/{chunk-nsvktvp4.js.map → chunk-5waxjsvv.js.map} +1 -1
- package/dist/{chunk-rfcygmf5.js → chunk-6w79zajj.js} +3 -3
- package/dist/{chunk-rfcygmf5.js.map → chunk-6w79zajj.js.map} +1 -1
- package/dist/{chunk-gb37722w.js → chunk-75ptmewf.js} +3 -3
- package/dist/{chunk-gb37722w.js.map → chunk-75ptmewf.js.map} +1 -1
- package/dist/{chunk-pyj7cd9t.js → chunk-851k0b26.js} +2 -2
- package/dist/{chunk-pyj7cd9t.js.map → chunk-851k0b26.js.map} +1 -1
- package/dist/{chunk-m6ystvtk.js → chunk-8reepafh.js} +2 -2
- package/dist/{chunk-m6ystvtk.js.map → chunk-8reepafh.js.map} +1 -1
- package/dist/{chunk-nvv9wej6.js → chunk-9hr0bcfy.js} +3 -3
- package/dist/{chunk-nvv9wej6.js.map → chunk-9hr0bcfy.js.map} +1 -1
- package/dist/{chunk-yqavgpwd.js → chunk-a9q2cr4w.js} +2 -2
- package/dist/{chunk-yqavgpwd.js.map → chunk-a9q2cr4w.js.map} +1 -1
- package/dist/{chunk-cy5qp6mz.js → chunk-amvy4r59.js} +2 -2
- package/dist/{chunk-cy5qp6mz.js.map → chunk-amvy4r59.js.map} +1 -1
- package/dist/{chunk-twnn7r66.js → chunk-b1mk12xg.js} +2 -2
- package/dist/{chunk-twnn7r66.js.map → chunk-b1mk12xg.js.map} +1 -1
- package/dist/{chunk-a6453d9s.js → chunk-b7cqwcbm.js} +2 -2
- package/dist/{chunk-a6453d9s.js.map → chunk-b7cqwcbm.js.map} +1 -1
- package/dist/{chunk-nncz308h.js → chunk-b7qjp7r1.js} +2 -2
- package/dist/{chunk-nncz308h.js.map → chunk-b7qjp7r1.js.map} +1 -1
- package/dist/chunk-beks65me.js +19 -0
- package/dist/{chunk-mb7q7s0a.js.map → chunk-beks65me.js.map} +3 -4
- package/dist/chunk-bf1ets45.js +5 -0
- package/dist/{chunk-11fsn5mr.js.map → chunk-bf1ets45.js.map} +4 -3
- package/dist/{chunk-9rchedr4.js → chunk-bhw7k8vp.js} +2 -2
- package/dist/{chunk-9rchedr4.js.map → chunk-bhw7k8vp.js.map} +1 -1
- package/dist/{chunk-k1vw22t2.js → chunk-ck0v2kzw.js} +2 -2
- package/dist/{chunk-k1vw22t2.js.map → chunk-ck0v2kzw.js.map} +1 -1
- package/dist/{chunk-e1n8zs3h.js → chunk-cptzbdn6.js} +2 -2
- package/dist/{chunk-e1n8zs3h.js.map → chunk-cptzbdn6.js.map} +1 -1
- package/dist/{chunk-6vr7f5fq.js → chunk-csbc1fxa.js} +3 -3
- package/dist/{chunk-6vr7f5fq.js.map → chunk-csbc1fxa.js.map} +1 -1
- package/dist/{chunk-kf71mjxa.js → chunk-d0trs736.js} +3 -3
- package/dist/{chunk-kf71mjxa.js.map → chunk-d0trs736.js.map} +1 -1
- package/dist/{chunk-zhs1r1z0.js → chunk-d8ekyng4.js} +3 -3
- package/dist/{chunk-zhs1r1z0.js.map → chunk-d8ekyng4.js.map} +1 -1
- package/dist/chunk-d9an2nra.js +5 -0
- package/dist/{chunk-hn67spz6.js.map → chunk-d9an2nra.js.map} +1 -1
- package/dist/{chunk-0d9qsmx2.js → chunk-dan79jab.js} +2 -2
- package/dist/{chunk-0d9qsmx2.js.map → chunk-dan79jab.js.map} +1 -1
- package/dist/{chunk-1yx2e0bh.js → chunk-ddad3902.js} +2 -2
- package/dist/{chunk-1yx2e0bh.js.map → chunk-ddad3902.js.map} +1 -1
- package/dist/{chunk-3cg7y62b.js → chunk-dm59ze55.js} +2 -2
- package/dist/{chunk-3cg7y62b.js.map → chunk-dm59ze55.js.map} +1 -1
- package/dist/{chunk-wvsv1jgg.js → chunk-dx7wpz5b.js} +2 -2
- package/dist/{chunk-wvsv1jgg.js.map → chunk-dx7wpz5b.js.map} +1 -1
- package/dist/{chunk-q9s7kwgt.js → chunk-eazqda9z.js} +3 -3
- package/dist/{chunk-q9s7kwgt.js.map → chunk-eazqda9z.js.map} +1 -1
- package/dist/{chunk-td8tha3j.js → chunk-es487acc.js} +1 -1
- package/dist/{chunk-9s851qz8.js → chunk-et3vhkbf.js} +2 -2
- package/dist/{chunk-9s851qz8.js.map → chunk-et3vhkbf.js.map} +1 -1
- package/dist/{chunk-qd2v93y4.js → chunk-f1y8eggf.js} +2 -2
- package/dist/{chunk-qd2v93y4.js.map → chunk-f1y8eggf.js.map} +1 -1
- package/dist/{chunk-1pem26zc.js → chunk-ga7c7tq0.js} +3 -3
- package/dist/{chunk-1pem26zc.js.map → chunk-ga7c7tq0.js.map} +1 -1
- package/dist/{chunk-c098fzvk.js → chunk-gcs9ydjv.js} +2 -2
- package/dist/{chunk-c098fzvk.js.map → chunk-gcs9ydjv.js.map} +1 -1
- package/dist/{chunk-bn5yn731.js → chunk-hfyxvdjj.js} +2 -2
- package/dist/{chunk-bn5yn731.js.map → chunk-hfyxvdjj.js.map} +1 -1
- package/dist/chunk-j0sncgxc.js +14 -0
- package/dist/{chunk-mn5xw79b.js.map → chunk-j0sncgxc.js.map} +6 -5
- package/dist/{chunk-p7r2w4qw.js → chunk-j9jqxv1d.js} +3 -3
- package/dist/{chunk-p7r2w4qw.js.map → chunk-j9jqxv1d.js.map} +1 -1
- package/dist/{chunk-jbrwt3cs.js → chunk-jdtn0zk2.js} +4 -4
- package/dist/{chunk-jbrwt3cs.js.map → chunk-jdtn0zk2.js.map} +1 -1
- package/dist/{chunk-s6jjy4y9.js → chunk-jn59bsww.js} +2 -2
- package/dist/{chunk-s6jjy4y9.js.map → chunk-jn59bsww.js.map} +1 -1
- package/dist/{chunk-he7z7y9j.js → chunk-kk502yk2.js} +2 -2
- package/dist/{chunk-he7z7y9j.js.map → chunk-kk502yk2.js.map} +1 -1
- package/dist/{chunk-wsttx9rg.js → chunk-mrdarm2q.js} +2 -2
- package/dist/{chunk-wsttx9rg.js.map → chunk-mrdarm2q.js.map} +1 -1
- package/dist/chunk-mvtgx1mr.js +4 -0
- package/dist/{chunk-x78jrs4y.js.map → chunk-mvtgx1mr.js.map} +2 -2
- package/dist/{chunk-et4pv1b1.js → chunk-mx9y9mtx.js} +1 -1
- package/dist/chunk-nv7mv51r.js +6 -0
- package/dist/{chunk-61f4m5px.js.map → chunk-nv7mv51r.js.map} +2 -2
- package/dist/{chunk-cttmy1jp.js → chunk-p2fhtf5r.js} +3 -3
- package/dist/{chunk-cttmy1jp.js.map → chunk-p2fhtf5r.js.map} +1 -1
- package/dist/{chunk-w7jsh3xd.js → chunk-qtbf3w6w.js} +2 -2
- package/dist/{chunk-w7jsh3xd.js.map → chunk-qtbf3w6w.js.map} +1 -1
- package/dist/chunk-qx87cdfg.js +5 -0
- package/dist/chunk-qx87cdfg.js.map +10 -0
- package/dist/{chunk-1kr25rcg.js → chunk-qyp652jz.js} +3 -3
- package/dist/{chunk-1kr25rcg.js.map → chunk-qyp652jz.js.map} +1 -1
- package/dist/{chunk-8b2tw2yp.js → chunk-rend2sbk.js} +1 -1
- package/dist/chunk-rx2shb3t.js +25 -0
- package/dist/chunk-rx2shb3t.js.map +19 -0
- package/dist/{chunk-mwqg079k.js → chunk-ryzcfxq7.js} +2 -2
- package/dist/{chunk-mwqg079k.js.map → chunk-ryzcfxq7.js.map} +1 -1
- package/dist/{chunk-7tx5y712.js → chunk-s9rfgxj5.js} +2 -2
- package/dist/{chunk-7tx5y712.js.map → chunk-s9rfgxj5.js.map} +1 -1
- package/dist/{chunk-1c1d0e60.js → chunk-scbvv2e4.js} +3 -3
- package/dist/{chunk-1c1d0e60.js.map → chunk-scbvv2e4.js.map} +1 -1
- package/dist/chunk-sj8jp4p9.js +24 -0
- package/dist/{chunk-k9wgtrc5.js.map → chunk-sj8jp4p9.js.map} +2 -2
- package/dist/{chunk-pwmgqq7z.js → chunk-teny6xkw.js} +2 -2
- package/dist/{chunk-pwmgqq7z.js.map → chunk-teny6xkw.js.map} +1 -1
- package/dist/{chunk-09ypnhjv.js → chunk-tmrmwthr.js} +2 -2
- package/dist/{chunk-09ypnhjv.js.map → chunk-tmrmwthr.js.map} +1 -1
- package/dist/{chunk-h4sw6nt3.js → chunk-vgdcz7tk.js} +3 -3
- package/dist/{chunk-h4sw6nt3.js.map → chunk-vgdcz7tk.js.map} +1 -1
- package/dist/{chunk-xk930yaw.js → chunk-wexs11yy.js} +2 -2
- package/dist/{chunk-xk930yaw.js.map → chunk-wexs11yy.js.map} +1 -1
- package/dist/{chunk-k1xt2tw7.js → chunk-xs4c2nvz.js} +2 -2
- package/dist/{chunk-k1xt2tw7.js.map → chunk-xs4c2nvz.js.map} +1 -1
- package/dist/{chunk-1va15sfq.js → chunk-xv74rhay.js} +2 -2
- package/dist/{chunk-1va15sfq.js.map → chunk-xv74rhay.js.map} +1 -1
- package/dist/{chunk-sq2wkynk.js → chunk-yv1psptb.js} +2 -2
- package/dist/{chunk-sq2wkynk.js.map → chunk-yv1psptb.js.map} +1 -1
- package/dist/{chunk-tk5q8hkv.js → chunk-zfter1x0.js} +4 -4
- package/dist/{chunk-tk5q8hkv.js.map → chunk-zfter1x0.js.map} +1 -1
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +214 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/useSubscription.d.ts +70 -0
- package/dist/client/useSubscription.d.ts.map +1 -0
- package/dist/config/index.js +1 -1
- package/dist/console/run.js +2 -2
- package/dist/console/run.js.map +2 -2
- package/dist/container/index.js +2 -2
- package/dist/container/index.js.map +1 -1
- package/dist/database/index.js +2 -2
- package/dist/database/index.js.map +1 -1
- package/dist/email/index.js +2 -2
- package/dist/email/index.js.map +1 -1
- package/dist/facades/ChangeFeed.d.ts +42 -0
- package/dist/facades/ChangeFeed.d.ts.map +1 -0
- package/dist/facades/index.d.ts +1 -0
- package/dist/facades/index.d.ts.map +1 -1
- package/dist/facades/index.js +2 -2
- package/dist/facades/index.js.map +1 -1
- package/dist/foundation/index.js +2 -2
- package/dist/foundation/index.js.map +1 -1
- package/dist/http/ResourcePolicy.d.ts +141 -0
- package/dist/http/ResourcePolicy.d.ts.map +1 -0
- package/dist/http/errors.d.ts +13 -0
- package/dist/http/errors.d.ts.map +1 -1
- package/dist/http/index.d.ts +2 -1
- package/dist/http/index.d.ts.map +1 -1
- package/dist/http/index.js +2 -2
- package/dist/http/index.js.map +1 -1
- package/dist/i18n/dictionaryRuntime.js +2 -2
- package/dist/i18n/dictionaryRuntime.js.map +1 -1
- package/dist/i18n/index.js +2 -2
- package/dist/i18n/index.js.map +2 -2
- package/dist/kernel/index.js +3 -3
- package/dist/kernel/index.js.map +3 -3
- package/dist/kernel/providers.d.ts.map +1 -1
- package/dist/orm/index.js +2 -2
- package/dist/orm/index.js.map +1 -1
- package/dist/server/index.js +2 -2
- package/dist/server/index.js.map +1 -1
- package/dist/services/change-feed/ChangeFeedDriver.d.ts +94 -0
- package/dist/services/change-feed/ChangeFeedDriver.d.ts.map +1 -0
- package/dist/services/change-feed/ChangeFeedManager.d.ts +166 -0
- package/dist/services/change-feed/ChangeFeedManager.d.ts.map +1 -0
- package/dist/services/change-feed/ChangeFeedServiceProvider.d.ts +11 -0
- package/dist/services/change-feed/ChangeFeedServiceProvider.d.ts.map +1 -0
- package/dist/services/change-feed/DatabaseChangeFeedDriver.d.ts +84 -0
- package/dist/services/change-feed/DatabaseChangeFeedDriver.d.ts.map +1 -0
- package/dist/services/change-feed/MemoryChangeFeedDriver.d.ts +26 -0
- package/dist/services/change-feed/MemoryChangeFeedDriver.d.ts.map +1 -0
- package/dist/services/change-feed/changeFeedDriverContract.d.ts +8 -0
- package/dist/services/change-feed/changeFeedDriverContract.d.ts.map +1 -0
- package/dist/services/change-feed/config.d.ts +42 -0
- package/dist/services/change-feed/config.d.ts.map +1 -0
- package/dist/services/change-feed/cursor.d.ts +17 -0
- package/dist/services/change-feed/cursor.d.ts.map +1 -0
- package/dist/services/change-feed/postgresListen.d.ts +30 -0
- package/dist/services/change-feed/postgresListen.d.ts.map +1 -0
- package/dist/services/change-feed/stream.d.ts +16 -0
- package/dist/services/change-feed/stream.d.ts.map +1 -0
- package/dist/services/change-feed/wire.d.ts +20 -0
- package/dist/services/change-feed/wire.d.ts.map +1 -0
- package/dist/services/index.d.ts +9 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +3 -3
- package/dist/services/index.js.map +2 -2
- package/dist/services/queue/work.js +2 -2
- package/dist/services/queue/work.js.map +1 -1
- package/dist/services/router/ViewRouteDispatcher.d.ts +16 -0
- package/dist/services/router/ViewRouteDispatcher.d.ts.map +1 -1
- package/dist/stats/route-table.js +1 -1
- package/dist/support/index.js +2 -2
- package/dist/support/index.js.map +1 -1
- package/dist/vitest/index.js +1 -1
- package/package.json +6 -2
- package/skills/gemi-react-best-practices/rules/controller-authorize-every-tenant-read.md +16 -1
- package/dist/chunk-11fsn5mr.js +0 -5
- package/dist/chunk-61f4m5px.js +0 -6
- package/dist/chunk-h3864a8z.js +0 -17
- package/dist/chunk-hn67spz6.js +0 -5
- package/dist/chunk-k9wgtrc5.js +0 -24
- package/dist/chunk-mb7q7s0a.js +0 -19
- package/dist/chunk-mn5xw79b.js +0 -9
- package/dist/chunk-x78jrs4y.js +0 -4
- /package/dist/{chunk-0sjh5v1n.js.map → chunk-53bek7sp.js.map} +0 -0
- /package/dist/{chunk-td8tha3j.js.map → chunk-es487acc.js.map} +0 -0
- /package/dist/{chunk-et4pv1b1.js.map → chunk-mx9y9mtx.js.map} +0 -0
- /package/dist/{chunk-8b2tw2yp.js.map → chunk-rend2sbk.js.map} +0 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { Job } from "../../services/queue/Job";
|
|
2
|
+
import type { GeneratedAttachment, ToolGenerateImageParams, ToolEditImageParams } from "../Agent";
|
|
3
|
+
import { type GenerateParams, type GenerateResult } from "../generate";
|
|
4
|
+
import type { ImageModel } from "../ImageModel";
|
|
5
|
+
import { ToolError } from "../redact";
|
|
6
|
+
import type { Infer, Schema } from "../Schema";
|
|
7
|
+
import { type Attachment, type AttachmentStorage, type AttachmentStore, ScopedAttachments } from "../store/Attachments";
|
|
8
|
+
import type { AgentError, Usage } from "../types";
|
|
9
|
+
import { type AgentJobRecord, type AgentJobStore } from "./AgentJobStore";
|
|
10
|
+
declare const HANDLE: unique symbol;
|
|
11
|
+
/**
|
|
12
|
+
* What `ctx.jobs.start` and `ctx.jobs.track` answer, and what a tool returns to
|
|
13
|
+
* say "this call goes on in the background" (#461).
|
|
14
|
+
*
|
|
15
|
+
* Returning it is what makes the call's result `running` rather than `ok`: the
|
|
16
|
+
* model reads that the job started and is told not to start it again, the turn
|
|
17
|
+
* goes on and ends as usual, and when the job settles the controller renders
|
|
18
|
+
* its outcome over that result the next time it loads the thread.
|
|
19
|
+
*
|
|
20
|
+
* `Output` is the job's settled output, and it is what the tool's output type
|
|
21
|
+
* becomes, so a client's `ToolShapes` see the job's result as the tool's.
|
|
22
|
+
*/
|
|
23
|
+
export declare class JobHandle<Output = unknown> {
|
|
24
|
+
/** The job's id. Hand it to whatever settles a tracked job. */
|
|
25
|
+
readonly id: string;
|
|
26
|
+
readonly toolCallId: string;
|
|
27
|
+
readonly summary: unknown;
|
|
28
|
+
/** Epoch milliseconds, on the job store's clock. */
|
|
29
|
+
readonly deadlineAt: number;
|
|
30
|
+
/** Phantom: the settled output's type. Never set. */
|
|
31
|
+
readonly $output: Output;
|
|
32
|
+
readonly [HANDLE]: true;
|
|
33
|
+
constructor(
|
|
34
|
+
/** The job's id. Hand it to whatever settles a tracked job. */
|
|
35
|
+
id: string, toolCallId: string, summary: unknown,
|
|
36
|
+
/** Epoch milliseconds, on the job store's clock. */
|
|
37
|
+
deadlineAt: number);
|
|
38
|
+
}
|
|
39
|
+
/** Whether a tool's return value is a `JobHandle`, across copies of the module. */
|
|
40
|
+
export declare function isJobHandle(value: unknown): value is JobHandle;
|
|
41
|
+
/**
|
|
42
|
+
* `ctx.jobs.start` or `track` from a run that has nowhere to settle a job
|
|
43
|
+
* into: a stateless turn, a run started without a job store, or a sub-run.
|
|
44
|
+
*
|
|
45
|
+
* A `ToolError`, so the model reads why the tool could not go to the
|
|
46
|
+
* background and can say so, rather than being told the tool broke.
|
|
47
|
+
*/
|
|
48
|
+
export declare class JobsRequireThreadError extends ToolError {
|
|
49
|
+
readonly code: "jobs_require_thread";
|
|
50
|
+
constructor(message: string);
|
|
51
|
+
}
|
|
52
|
+
/** What a job settles with. */
|
|
53
|
+
export type AgentJobOutcome = {
|
|
54
|
+
output: unknown;
|
|
55
|
+
usage?: Usage;
|
|
56
|
+
} | {
|
|
57
|
+
error: string | Error | (Pick<AgentError, "message"> & Partial<AgentError>);
|
|
58
|
+
usage?: Usage;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Background jobs, from anywhere in the app: settle one, fail one, look one up.
|
|
62
|
+
*
|
|
63
|
+
* PROCESS-WIDE, and that is forced. A job is started by a tool inside a run,
|
|
64
|
+
* and settled by a queue worker, a provider's webhook, a poller or the deadline
|
|
65
|
+
* sweep, none of which has a controller to read a store from. So the store is
|
|
66
|
+
* set once, at boot, for every one of them:
|
|
67
|
+
*
|
|
68
|
+
* AgentJobs.use(new DatabaseAgentJobStore(app(DatabaseManager).connection()));
|
|
69
|
+
*
|
|
70
|
+
* Until then it is a `MemoryAgentJobStore`, which works in one process and
|
|
71
|
+
* forgets on restart.
|
|
72
|
+
*/
|
|
73
|
+
export declare const AgentJobs: {
|
|
74
|
+
/** The store every part of the feature reads and writes. */
|
|
75
|
+
readonly store: AgentJobStore;
|
|
76
|
+
/** Sets the store. Call it once, at boot, in every process that starts or runs jobs. */
|
|
77
|
+
use(store: AgentJobStore): void;
|
|
78
|
+
get(id: string): Promise<AgentJobRecord | null>;
|
|
79
|
+
/**
|
|
80
|
+
* Settles a running job with its output or its error, and answers whether
|
|
81
|
+
* this call did it.
|
|
82
|
+
*
|
|
83
|
+
* COMPARE-AND-SET FROM `running`. The first settle wins and every later one
|
|
84
|
+
* answers `false` and changes nothing, so a webhook, a poller and the
|
|
85
|
+
* deadline sweep can all race on one job. A job the deadline sweep has
|
|
86
|
+
* already failed stays failed: a late result is refused, so the model never
|
|
87
|
+
* sees a job flip from failed to done.
|
|
88
|
+
*
|
|
89
|
+
* An error given as a `ToolError`, a string or an `AgentError`-like object is
|
|
90
|
+
* shown to the model as it is. Any other `Error` is logged in full and the
|
|
91
|
+
* model is told only that the job failed, as for a tool that throws (#446).
|
|
92
|
+
*/
|
|
93
|
+
settle(id: string, outcome: AgentJobOutcome): Promise<boolean>;
|
|
94
|
+
/** `settle(id, { error })`. */
|
|
95
|
+
fail(id: string, error: string | Error | AgentError): Promise<boolean>;
|
|
96
|
+
/**
|
|
97
|
+
* The deadline sweep: fails every running job whose deadline has passed
|
|
98
|
+
* with code `"timeout"`, and answers how many it failed.
|
|
99
|
+
*
|
|
100
|
+
* Compare-and-set like every settle, so it is safe to run on every
|
|
101
|
+
* instance at once, and a result that arrives after it is refused. Run it
|
|
102
|
+
* every minute with `AgentJobDeadlineSweep`; the controller also checks a
|
|
103
|
+
* thread's jobs when it loads the thread, so an app without cron still sees
|
|
104
|
+
* overdue jobs fail, just later. The job's queue worker is not stopped: what
|
|
105
|
+
* it returns afterwards is dropped.
|
|
106
|
+
*/
|
|
107
|
+
sweep(options?: {
|
|
108
|
+
limit?: number;
|
|
109
|
+
}): Promise<number>;
|
|
110
|
+
};
|
|
111
|
+
/** The store's clock, or this process's for a store without one. */
|
|
112
|
+
export declare function clockOf(store: AgentJobStore): Promise<number>;
|
|
113
|
+
/** Fails a running job for its deadline. Compare-and-set: false when it had settled. */
|
|
114
|
+
export declare function expire(store: AgentJobStore, record: AgentJobRecord): Promise<boolean>;
|
|
115
|
+
/** Options for `ctx.jobs.start` and `ctx.jobs.track`. */
|
|
116
|
+
export type StartJobOptions = {
|
|
117
|
+
/**
|
|
118
|
+
* What the model and the UI see while the job runs, in place of a result:
|
|
119
|
+
* which images, which pages. Plain data, and keep it small, since it is in
|
|
120
|
+
* the history on every later turn.
|
|
121
|
+
*/
|
|
122
|
+
summary?: unknown;
|
|
123
|
+
/**
|
|
124
|
+
* How long the job may run, in milliseconds. Defaults to the tool's
|
|
125
|
+
* `async.deadlineMs`, else an hour. A job still running then is failed with
|
|
126
|
+
* code `"timeout"` by the deadline sweep, and a later result is refused.
|
|
127
|
+
*/
|
|
128
|
+
deadlineMs?: number;
|
|
129
|
+
};
|
|
130
|
+
/** A tool's `ctx.jobs`. See `ToolContext.jobs`. */
|
|
131
|
+
export interface ToolJobs {
|
|
132
|
+
/**
|
|
133
|
+
* Records a background job for this tool call and queues `job` to do it.
|
|
134
|
+
* Return the handle from `execute` to make the call's result `running`.
|
|
135
|
+
*
|
|
136
|
+
* At least once, like every queued job: `job.run` may run again after a
|
|
137
|
+
* crash, so make it idempotent. Only on a threaded run (a turn with a
|
|
138
|
+
* `threadId` through `AgentController`), and only from a top-level tool.
|
|
139
|
+
*/
|
|
140
|
+
start<A, O>(job: AgentJobClass<A, O>, args: A, options?: StartJobOptions): Promise<JobHandle<O>>;
|
|
141
|
+
/**
|
|
142
|
+
* Records a background job that something else settles: a provider's
|
|
143
|
+
* webhook, a poller. Pass `handle.id` to it, and call
|
|
144
|
+
* `AgentJobs.settle(id, { output })` when the work is done.
|
|
145
|
+
*/
|
|
146
|
+
track<O = unknown>(options?: StartJobOptions): Promise<JobHandle<O>>;
|
|
147
|
+
}
|
|
148
|
+
/** What a run that may start jobs is given. `AgentController` passes it on a threaded turn. */
|
|
149
|
+
export type RunJobs = {
|
|
150
|
+
/** The run's owner (`runOwner`), recorded on each job. */
|
|
151
|
+
owner: string | null;
|
|
152
|
+
};
|
|
153
|
+
/** The longest a job runs when nothing says otherwise. */
|
|
154
|
+
export declare const DEFAULT_JOB_DEADLINE_MS: number;
|
|
155
|
+
/** @internal `ctx.jobs` for one tool call. Built by the run, per call. */
|
|
156
|
+
export declare function toolJobs(params: {
|
|
157
|
+
jobs: RunJobs | undefined;
|
|
158
|
+
threadId: string | undefined;
|
|
159
|
+
runId: string;
|
|
160
|
+
toolCallId: string;
|
|
161
|
+
toolName: string;
|
|
162
|
+
depth: number;
|
|
163
|
+
/** The tool's `async` declaration; `undefined` for a tool without one. */
|
|
164
|
+
async: {
|
|
165
|
+
deadlineMs?: number;
|
|
166
|
+
} | undefined;
|
|
167
|
+
attachments: ScopedAttachments | null;
|
|
168
|
+
}): ToolJobs;
|
|
169
|
+
/** An `AgentJob` subclass, as `ctx.jobs.start` takes it. */
|
|
170
|
+
export type AgentJobClass<A, O> = new () => AgentJob<A, O>;
|
|
171
|
+
/** `generateImage`'s params inside a job: as in a tool, without `showModel` (there is no run to show). */
|
|
172
|
+
export type JobGenerateImageParams = Omit<ToolGenerateImageParams, "showModel">;
|
|
173
|
+
export type JobEditImageParams = Omit<ToolEditImageParams, "showModel">;
|
|
174
|
+
/** Attachments inside a job: the scope of the run that started it. */
|
|
175
|
+
export interface JobAttachments {
|
|
176
|
+
put(blob: Blob, params?: {
|
|
177
|
+
name?: string;
|
|
178
|
+
mimeType?: string;
|
|
179
|
+
}): Promise<Attachment>;
|
|
180
|
+
get(id: string): Promise<Attachment>;
|
|
181
|
+
read: ScopedAttachments["read"];
|
|
182
|
+
file(id: string): Promise<File>;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* What `AgentJob.run` is handed beside its arguments: the parts of a tool's
|
|
186
|
+
* `ToolContext` that still mean something with no run around them.
|
|
187
|
+
*/
|
|
188
|
+
export interface AgentJobContext {
|
|
189
|
+
/** The job's id (`ajob_…`). */
|
|
190
|
+
readonly id: string;
|
|
191
|
+
readonly threadId: string;
|
|
192
|
+
readonly toolCallId: string;
|
|
193
|
+
readonly toolName: string;
|
|
194
|
+
/** The `runOwner` of the run that started it. */
|
|
195
|
+
readonly owner: string | null;
|
|
196
|
+
readonly summary: unknown;
|
|
197
|
+
/** Not aborted yet: cancellation comes with a later release (#461, phase 4). */
|
|
198
|
+
readonly signal: AbortSignal;
|
|
199
|
+
/**
|
|
200
|
+
* The attachments of the run that started the job: what the tool's
|
|
201
|
+
* `ctx.attachments` was. Throws when that run had no attachment scope.
|
|
202
|
+
*/
|
|
203
|
+
readonly attachments: JobAttachments;
|
|
204
|
+
/** `generate`, with its usage counted on the job. See `ToolContext.generate`. */
|
|
205
|
+
generate<O extends Schema<any>>(params: GenerateParams<O>): Promise<GenerateResult<Infer<O>>>;
|
|
206
|
+
/** Renders an image and stores it under the run's attachments. Usage is counted on the job. */
|
|
207
|
+
generateImage(model: ImageModel, params: JobGenerateImageParams): Promise<GeneratedAttachment>;
|
|
208
|
+
/** Edits images (bytes or attachment ids) and stores the result. Usage is counted on the job. */
|
|
209
|
+
editImage(model: ImageModel, params: JobEditImageParams): Promise<GeneratedAttachment>;
|
|
210
|
+
/** What this attempt has spent so far. */
|
|
211
|
+
readonly usage: Usage;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* A queued job that settles a tool call (#461).
|
|
215
|
+
*
|
|
216
|
+
* class RenderImagesJob extends AgentJob<{ pageId: number; prompts: string[] }, { made: number }> {
|
|
217
|
+
* static name = "RenderImagesJob";
|
|
218
|
+
* async run({ pageId, prompts }, job) {
|
|
219
|
+
* for (const prompt of prompts) await job.generateImage(model, { prompt });
|
|
220
|
+
* return { made: prompts.length };
|
|
221
|
+
* }
|
|
222
|
+
* }
|
|
223
|
+
*
|
|
224
|
+
* A gemi `Job`, so it gets the queue's leases, retries, backoff and dead
|
|
225
|
+
* letters. Register it with the queue like any other job. What `run` returns
|
|
226
|
+
* settles the tool call `ok`; a throw on the last attempt settles it `error`.
|
|
227
|
+
* At least once: make `run` idempotent.
|
|
228
|
+
*
|
|
229
|
+
* Declare `run` as a method, not as an arrow-function field. Override
|
|
230
|
+
* `onDeadletter` only with a call to `super.onDeadletter`, which is what fails
|
|
231
|
+
* the job. `worker = true` is not supported. The queue hands `uniqueId`,
|
|
232
|
+
* `throttle`, `concurrency`, `onFail` and `onDeadletter` the envelope
|
|
233
|
+
* `{ jobId, args }`, not `args`.
|
|
234
|
+
*/
|
|
235
|
+
export declare abstract class AgentJob<Args = unknown, Output = unknown> extends Job {
|
|
236
|
+
/** Phantom: the arguments' type. Never set. */
|
|
237
|
+
readonly $args: Args;
|
|
238
|
+
/** Phantom: the output's type. Never set. */
|
|
239
|
+
readonly $output: Output;
|
|
240
|
+
/**
|
|
241
|
+
* Where the job's `attachments` records live. Set it to what the
|
|
242
|
+
* controller's `attachments` is, as for the controller itself.
|
|
243
|
+
*/
|
|
244
|
+
attachments: AttachmentStore;
|
|
245
|
+
/** Where the attachments' bytes live. Defaults to the app's `Storage`. */
|
|
246
|
+
attachmentStorage: AttachmentStorage;
|
|
247
|
+
abstract run(args: Args, job: AgentJobContext): Promise<Output> | Output;
|
|
248
|
+
constructor();
|
|
249
|
+
/**
|
|
250
|
+
* Fails the job once the queue has given up on it: its last attempt threw,
|
|
251
|
+
* it called `this.fail(error, { retry: false })`, or its process died on the
|
|
252
|
+
* last attempt.
|
|
253
|
+
*/
|
|
254
|
+
onDeadletter(error: Error, ..._args: any[]): void;
|
|
255
|
+
/** @internal The queue-facing `run`: see the constructor. */
|
|
256
|
+
private $runEnvelope;
|
|
257
|
+
}
|
|
258
|
+
export {};
|
|
259
|
+
//# sourceMappingURL=AgentJob.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgentJob.d.ts","sourceRoot":"","sources":["../../../ai/jobs/AgentJob.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { CronJob } from "../../services/cron/CronJob";
|
|
2
|
+
/**
|
|
3
|
+
* Fails background jobs that ran past their deadline (#461), every minute.
|
|
4
|
+
*
|
|
5
|
+
* Schedule it by exporting it from a file under `app/cron`:
|
|
6
|
+
*
|
|
7
|
+
* export { AgentJobDeadlineSweep } from "gemi/ai";
|
|
8
|
+
*
|
|
9
|
+
* Safe on every instance at once: each job is failed by compare-and-set. An
|
|
10
|
+
* app without it still sees an overdue job fail, when the controller next
|
|
11
|
+
* loads the job's thread.
|
|
12
|
+
*/
|
|
13
|
+
export declare class AgentJobDeadlineSweep extends CronJob {
|
|
14
|
+
name: string;
|
|
15
|
+
cron: string;
|
|
16
|
+
callback(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=AgentJobDeadlineSweep.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgentJobDeadlineSweep.d.ts","sourceRoot":"","sources":["../../../ai/jobs/AgentJobDeadlineSweep.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAGtD;;;;;;;;;;GAUG;AACH,qBAAa,qBAAsB,SAAQ,OAAO;IAChD,IAAI,SAA2B;IAC/B,IAAI,SAAe;IAEb,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAOhC"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import type { AgentError, Usage } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Where a background job stands (#461).
|
|
4
|
+
*
|
|
5
|
+
* `running` until something settles it; `ok` and `error` are final. A job
|
|
6
|
+
* moves out of `running` once, by compare-and-set (`AgentJobStore.transition`),
|
|
7
|
+
* so a queue worker, a provider's webhook, a poller and the deadline sweep can
|
|
8
|
+
* all race to settle the same job and exactly one of them wins.
|
|
9
|
+
*/
|
|
10
|
+
export type AgentJobState = "running" | "ok" | "error";
|
|
11
|
+
/**
|
|
12
|
+
* One background job, as the job store keeps it.
|
|
13
|
+
*
|
|
14
|
+
* The record is the job's state, and it is NOT the tool result. The tool
|
|
15
|
+
* result in the thread says `running` and points here by `id`; the controller
|
|
16
|
+
* renders the record's current state over it whenever it loads the thread (see
|
|
17
|
+
* `overlayJobs`). The record is kept apart from the messages because a live
|
|
18
|
+
* run writes whole messages to the store, and a job settling during that run
|
|
19
|
+
* would race those writes and lose.
|
|
20
|
+
*/
|
|
21
|
+
export type AgentJobRecord = {
|
|
22
|
+
/** `ajob_…`. Handed to the app (`JobHandle.id`) to settle a tracked job. */
|
|
23
|
+
id: string;
|
|
24
|
+
threadId: string;
|
|
25
|
+
/** The run whose tool started the job. */
|
|
26
|
+
runId: string;
|
|
27
|
+
/** The tool call whose result this job settles. */
|
|
28
|
+
toolCallId: string;
|
|
29
|
+
toolName: string;
|
|
30
|
+
/** The `runOwner` of the run that started it, or `null` for an anonymous run. */
|
|
31
|
+
owner: string | null;
|
|
32
|
+
/** The `AgentJob` class's queue name, or `null` for a job made with `track`. */
|
|
33
|
+
job: string | null;
|
|
34
|
+
/**
|
|
35
|
+
* What the tool said about the job when it started it: what the model and
|
|
36
|
+
* the UI see while it runs. Server-owned, and kept small by the tool.
|
|
37
|
+
*/
|
|
38
|
+
summary?: unknown;
|
|
39
|
+
state: AgentJobState;
|
|
40
|
+
/** The settled output, on `ok`. */
|
|
41
|
+
output?: unknown;
|
|
42
|
+
/** Why it failed, on `error`. Already redacted: this is what the model reads. */
|
|
43
|
+
error?: AgentError;
|
|
44
|
+
/** What the job spent on model and image calls. Counted on the turn that started it. */
|
|
45
|
+
usage?: Usage;
|
|
46
|
+
/**
|
|
47
|
+
* Set when the job's tool result never reached the thread: the run died
|
|
48
|
+
* after the job started and before the result was stored. The job still
|
|
49
|
+
* runs and settles; nothing in the thread shows it.
|
|
50
|
+
*/
|
|
51
|
+
orphaned?: true;
|
|
52
|
+
/**
|
|
53
|
+
* The attachment scope key of the run that started the job, so the job's
|
|
54
|
+
* `attachments` are the ones the tool would have had. `null` when the run
|
|
55
|
+
* had none.
|
|
56
|
+
*/
|
|
57
|
+
attachmentScope: string | null;
|
|
58
|
+
/** Epoch milliseconds, on the store's clock. */
|
|
59
|
+
createdAt: number;
|
|
60
|
+
updatedAt: number;
|
|
61
|
+
/** When the deadline sweep fails the job if it is still running. */
|
|
62
|
+
deadlineAt: number;
|
|
63
|
+
settledAt?: number;
|
|
64
|
+
};
|
|
65
|
+
/** What `create` is given: the record minus what the store stamps. */
|
|
66
|
+
export type NewAgentJobRecord = Omit<AgentJobRecord, "state" | "createdAt" | "updatedAt" | "deadlineAt" | "settledAt"> & {
|
|
67
|
+
/** How long from now the job may run, in milliseconds. */
|
|
68
|
+
deadlineMs: number;
|
|
69
|
+
};
|
|
70
|
+
/** The fields a transition may write. `id`, the thread and the call never change. */
|
|
71
|
+
export type AgentJobUpdate = Partial<Pick<AgentJobRecord, "state" | "output" | "error" | "usage" | "orphaned" | "settledAt">>;
|
|
72
|
+
/**
|
|
73
|
+
* Where background jobs live.
|
|
74
|
+
*
|
|
75
|
+
* `MemoryAgentJobStore` is the default and is not durable. `DatabaseAgentJobStore`
|
|
76
|
+
* keeps them in a table. An app that already has a jobs table can implement
|
|
77
|
+
* this over it.
|
|
78
|
+
*/
|
|
79
|
+
export interface AgentJobStore {
|
|
80
|
+
/** Writes a new `running` record and returns it as stored. */
|
|
81
|
+
create(job: NewAgentJobRecord): Promise<AgentJobRecord>;
|
|
82
|
+
get(id: string): Promise<AgentJobRecord | null>;
|
|
83
|
+
/**
|
|
84
|
+
* A thread's jobs, newest first. `states` filters, `limit` bounds. Each
|
|
85
|
+
* record is a copy the caller may keep.
|
|
86
|
+
*/
|
|
87
|
+
listForThread(threadId: string, options?: {
|
|
88
|
+
states?: AgentJobState[];
|
|
89
|
+
limit?: number;
|
|
90
|
+
}): Promise<AgentJobRecord[]>;
|
|
91
|
+
/**
|
|
92
|
+
* Compare-and-set: applies `to` only when the job's state is one of `from`,
|
|
93
|
+
* and answers whether it did. Bumps `updatedAt`, and stamps `settledAt` when
|
|
94
|
+
* `to.state` moves the job out of `running`.
|
|
95
|
+
*/
|
|
96
|
+
transition(id: string, from: AgentJobState[], to: AgentJobUpdate): Promise<boolean>;
|
|
97
|
+
/** Running jobs whose `deadlineAt` is at or before `now`, oldest deadline first. */
|
|
98
|
+
overdue(now: number, limit: number): Promise<AgentJobRecord[]>;
|
|
99
|
+
/**
|
|
100
|
+
* The store's clock, in epoch milliseconds. The deadline sweep compares
|
|
101
|
+
* `deadlineAt` against this rather than the process's clock. Optional: a
|
|
102
|
+
* store without one is compared against `Date.now()`.
|
|
103
|
+
*/
|
|
104
|
+
now?(): Promise<number>;
|
|
105
|
+
/**
|
|
106
|
+
* Runs `fn` in a transaction, so `ctx.jobs.start` writes the record and
|
|
107
|
+
* queues the job together: both or neither. Optional: without it the record
|
|
108
|
+
* is written first, and a dispatch that fails then fails the record.
|
|
109
|
+
*/
|
|
110
|
+
transaction?<T>(fn: () => Promise<T>): Promise<T>;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Jobs in a map, for as long as the process lives.
|
|
114
|
+
*
|
|
115
|
+
* NOT DURABLE, like `MemoryAgentStore`: a restart loses every record, and a
|
|
116
|
+
* job that was running is then lost too. The tool result that pointed at it
|
|
117
|
+
* reads as a lost job on the next turn. It is the default so that jobs work in
|
|
118
|
+
* development and tests without a table; use `DatabaseAgentJobStore` in
|
|
119
|
+
* production.
|
|
120
|
+
*
|
|
121
|
+
* It only works when the queue runs the jobs in this same process (the memory
|
|
122
|
+
* queue driver, or a database driver claiming here), since a worker in another
|
|
123
|
+
* process has a map of its own.
|
|
124
|
+
*/
|
|
125
|
+
export declare class MemoryAgentJobStore implements AgentJobStore {
|
|
126
|
+
private jobs;
|
|
127
|
+
create(job: NewAgentJobRecord): Promise<AgentJobRecord>;
|
|
128
|
+
get(id: string): Promise<AgentJobRecord | null>;
|
|
129
|
+
listForThread(threadId: string, options?: {
|
|
130
|
+
states?: AgentJobState[];
|
|
131
|
+
limit?: number;
|
|
132
|
+
}): Promise<AgentJobRecord[]>;
|
|
133
|
+
transition(id: string, from: AgentJobState[], to: AgentJobUpdate): Promise<boolean>;
|
|
134
|
+
overdue(now: number, limit: number): Promise<AgentJobRecord[]>;
|
|
135
|
+
now(): Promise<number>;
|
|
136
|
+
/** Bounds a long-lived thread: running jobs are never dropped, settled ones oldest first. */
|
|
137
|
+
private trim;
|
|
138
|
+
}
|
|
139
|
+
/** Newest first, with the id as a tie-break so the order is stable. */
|
|
140
|
+
export declare function newestFirst(a: AgentJobRecord, b: AgentJobRecord): number;
|
|
141
|
+
//# sourceMappingURL=AgentJobStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgentJobStore.d.ts","sourceRoot":"","sources":["../../../ai/jobs/AgentJobStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { DatabaseConnection } from "../../database/Connection";
|
|
2
|
+
import type { Dialect } from "../../database/dialect";
|
|
3
|
+
import type { AgentJobRecord, AgentJobState, AgentJobStore, AgentJobUpdate, NewAgentJobRecord } from "./AgentJobStore";
|
|
4
|
+
export type DatabaseAgentJobStoreOptions = {
|
|
5
|
+
/**
|
|
6
|
+
* The table. Default `gemi_agent_jobs`. A plain identifier (letters, digits
|
|
7
|
+
* and underscores), because it is spliced into every statement.
|
|
8
|
+
*/
|
|
9
|
+
table?: string;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Background jobs (#461) in a table of the app's own database, so a job and
|
|
13
|
+
* its outcome outlive the process: a deploy in the middle of a render no
|
|
14
|
+
* longer loses it, and every instance sees the same state.
|
|
15
|
+
*
|
|
16
|
+
* Opt in, like the agent store:
|
|
17
|
+
*
|
|
18
|
+
* AgentJobs.use(new DatabaseAgentJobStore(app(DatabaseManager).connection()));
|
|
19
|
+
*
|
|
20
|
+
* Written for SQLite, Postgres and MySQL 8 / MariaDB 10.6+ in raw SQL, as the
|
|
21
|
+
* database queue driver is, and the table is the app's to create: add the
|
|
22
|
+
* Prisma model from the docs, or call `createTable()`.
|
|
23
|
+
*
|
|
24
|
+
* - **Compare-and-set** is `UPDATE … WHERE id = ? AND state IN (…)`, so two
|
|
25
|
+
* instances settling one job cannot both win.
|
|
26
|
+
* - **Time** is epoch milliseconds read from the database's clock, so the
|
|
27
|
+
* deadline sweep on any instance agrees on when a job is overdue.
|
|
28
|
+
* - **Transactions.** `ctx.jobs.start` writes the record and queues the job
|
|
29
|
+
* inside `transaction()`. On Postgres and MySQL, with the database queue
|
|
30
|
+
* driver on the same connection, both rows commit together or not at all.
|
|
31
|
+
* With any other queue the dispatch is held until the record has committed.
|
|
32
|
+
*/
|
|
33
|
+
export declare class DatabaseAgentJobStore implements AgentJobStore {
|
|
34
|
+
readonly table: string;
|
|
35
|
+
private readonly sql;
|
|
36
|
+
private readonly dialect;
|
|
37
|
+
private readonly connection;
|
|
38
|
+
constructor(connection: Pick<DatabaseConnection, "sql" | "dialect"> & Partial<Pick<DatabaseConnection, "name">>, options?: DatabaseAgentJobStoreOptions);
|
|
39
|
+
/**
|
|
40
|
+
* Creates the table and its indexes if they do not exist: the DDL Prisma
|
|
41
|
+
* generates for the model in the docs. For tests and for an app that does
|
|
42
|
+
* not manage its schema with Prisma.
|
|
43
|
+
*/
|
|
44
|
+
createTable(): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Runs `fn` in a transaction on this store's connection, joining one that is
|
|
47
|
+
* already open on it. `ctx.jobs.start` writes the record and queues the job
|
|
48
|
+
* in here.
|
|
49
|
+
*/
|
|
50
|
+
transaction<T>(fn: () => Promise<T>): Promise<T>;
|
|
51
|
+
create(job: NewAgentJobRecord): Promise<AgentJobRecord>;
|
|
52
|
+
get(id: string): Promise<AgentJobRecord | null>;
|
|
53
|
+
listForThread(threadId: string, options?: {
|
|
54
|
+
states?: AgentJobState[];
|
|
55
|
+
limit?: number;
|
|
56
|
+
}): Promise<AgentJobRecord[]>;
|
|
57
|
+
transition(id: string, from: AgentJobState[], to: AgentJobUpdate): Promise<boolean>;
|
|
58
|
+
overdue(now: number, limit: number): Promise<AgentJobRecord[]>;
|
|
59
|
+
now(): Promise<number>;
|
|
60
|
+
/**
|
|
61
|
+
* Deletes settled jobs that settled more than `olderThanMs` ago, and answers
|
|
62
|
+
* how many. A settled result is written back into the thread on the next
|
|
63
|
+
* turn, after which the record is only history; nothing removes it unless
|
|
64
|
+
* this is called, from a cron job say. Running jobs are never pruned.
|
|
65
|
+
*/
|
|
66
|
+
prune(olderThanMs: number): Promise<number>;
|
|
67
|
+
/** The open ORM transaction, when it is on this store's connection. */
|
|
68
|
+
private joinable;
|
|
69
|
+
/** Read at each call and never kept: a stored transaction handle outlives its transaction. */
|
|
70
|
+
private q;
|
|
71
|
+
private column;
|
|
72
|
+
private name;
|
|
73
|
+
/** The database's clock, in epoch milliseconds. As in `DatabaseQueueDriver`. */
|
|
74
|
+
private clock;
|
|
75
|
+
private ms;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* The table as Prisma generates it for the model in the docs, with
|
|
79
|
+
* `IF NOT EXISTS` added.
|
|
80
|
+
*/
|
|
81
|
+
export declare function createAgentJobsTableStatements(dialect: Dialect, table: string): string[];
|
|
82
|
+
//# sourceMappingURL=DatabaseAgentJobStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DatabaseAgentJobStore.d.ts","sourceRoot":"","sources":["../../../ai/jobs/DatabaseAgentJobStore.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEtD,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,aAAa,EACb,cAAc,EACd,iBAAiB,EAClB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,MAAM,4BAA4B,GAAG;IACzC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAIF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,qBAAsB,YAAW,aAAa;IACzD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;gBAG9C,UAAU,EAAE,IAAI,CAAC,kBAAkB,EAAE,KAAK,GAAG,SAAS,CAAC,GACrD,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,EAC3C,OAAO,GAAE,4BAAiC;IAc5C;;;;OAIG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAMlC;;;;OAIG;IACG,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAOhD,MAAM,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC;IAkBvD,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAM/C,aAAa,CACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,GACzD,OAAO,CAAC,cAAc,EAAE,CAAC;IAwBtB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IA0BnF,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAW9D,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;IAM5B;;;;;OAKG;IACG,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IASjD,uEAAuE;IACvE,OAAO,CAAC,QAAQ;IAOhB,8FAA8F;IAC9F,OAAO,CAAC,CAAC;IAIT,OAAO,CAAC,MAAM;IAKd,OAAO,CAAC,IAAI;IAKZ,gFAAgF;IAChF,OAAO,CAAC,KAAK;IAYb,OAAO,CAAC,EAAE;CAMX;AAqDD;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAyDxF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { AgentJobRecord } from "./AgentJobStore";
|
|
2
|
+
/** How many jobs the `<jobs>` block lists by default. */
|
|
3
|
+
export declare const DEFAULT_JOBS_CONTEXT_MAX = 20;
|
|
4
|
+
/** `Agent.create({ jobs })`. */
|
|
5
|
+
export type AgentJobsOptions = {
|
|
6
|
+
/**
|
|
7
|
+
* The `<jobs>` block added to the system prompt on a thread that has
|
|
8
|
+
* background jobs: at most `max` of them (default 20), running ones first,
|
|
9
|
+
* then the newest settled. `false` leaves it out.
|
|
10
|
+
*/
|
|
11
|
+
contextBlock?: {
|
|
12
|
+
max?: number;
|
|
13
|
+
} | false;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* The `<jobs>` block (#461): what the model is told about the thread's
|
|
17
|
+
* background jobs on every turn, beside the tool results in the history.
|
|
18
|
+
*
|
|
19
|
+
* The history already shows each job's call and its `running` or settled
|
|
20
|
+
* result. The block is for what the history cannot show: a job whose result
|
|
21
|
+
* never reached the thread (an orphan), and a list in one place, so a model
|
|
22
|
+
* asked to "make the images" sees that a job for them is already running
|
|
23
|
+
* rather than starting another.
|
|
24
|
+
*
|
|
25
|
+
* Bounded by count, `max`, running before settled and newest first inside
|
|
26
|
+
* each. Times are absolute (UTC) rather than ages, so the block is the same
|
|
27
|
+
* text from one turn to the next until a job starts or settles, and the
|
|
28
|
+
* prompt cache holds in between. `null` when there is nothing to list.
|
|
29
|
+
*/
|
|
30
|
+
export declare function renderJobsBlock(jobs: AgentJobRecord[], max: number): string | null;
|
|
31
|
+
//# sourceMappingURL=contextBlock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contextBlock.d.ts","sourceRoot":"","sources":["../../../ai/jobs/contextBlock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,yDAAyD;AACzD,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C,gCAAgC;AAChC,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;;;OAIG;IACH,YAAY,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,KAAK,CAAC;CACzC,CAAC;AAKF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmClF"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { AgentJob, type AgentJobClass, type AgentJobContext, type AgentJobOutcome, AgentJobs, DEFAULT_JOB_DEADLINE_MS, type JobAttachments, type JobEditImageParams, type JobGenerateImageParams, JobHandle, JobsRequireThreadError, type RunJobs, type StartJobOptions, type ToolJobs, } from "./AgentJob";
|
|
2
|
+
export { type AgentJobRecord, type AgentJobState, type AgentJobStore, type AgentJobUpdate, MemoryAgentJobStore, type NewAgentJobRecord, } from "./AgentJobStore";
|
|
3
|
+
export { AgentJobDeadlineSweep } from "./AgentJobDeadlineSweep";
|
|
4
|
+
export { type AgentJobsOptions, DEFAULT_JOBS_CONTEXT_MAX } from "./contextBlock";
|
|
5
|
+
export { DatabaseAgentJobStore, type DatabaseAgentJobStoreOptions } from "./DatabaseAgentJobStore";
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../ai/jobs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,SAAS,EACT,uBAAuB,EACvB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,SAAS,EACT,sBAAsB,EACtB,KAAK,OAAO,EACZ,KAAK,eAAe,EACpB,KAAK,QAAQ,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,mBAAmB,EACnB,KAAK,iBAAiB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,KAAK,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,KAAK,4BAA4B,EAAE,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Schema } from "../Schema";
|
|
2
|
+
import type { AgentMessage } from "../types";
|
|
3
|
+
import type { AgentJobRecord, AgentJobStore } from "./AgentJobStore";
|
|
4
|
+
/**
|
|
5
|
+
* The thread with each background job's current state rendered over the tool
|
|
6
|
+
* result that points at it (#461).
|
|
7
|
+
*
|
|
8
|
+
* A tool that returned a `JobHandle` left a `running` result in the thread.
|
|
9
|
+
* The job settles later, into the job store, and never into the messages: a
|
|
10
|
+
* live run writes whole messages, and a settle racing those writes would be
|
|
11
|
+
* overwritten by the run's stale copy. So the messages are brought up to date
|
|
12
|
+
* here, when the thread is loaded, which `AgentController` does under the
|
|
13
|
+
* thread's lock before a turn and without writing for `readThread`.
|
|
14
|
+
*
|
|
15
|
+
* - A `running` result whose job settled becomes the job's `ok` or `error`
|
|
16
|
+
* result, in place, with the job still named on it (`job`).
|
|
17
|
+
* - A `running` result whose job is still running is left exactly as it is,
|
|
18
|
+
* so the request stays byte-identical, and the prompt cache with it, until
|
|
19
|
+
* the job settles.
|
|
20
|
+
* - A `running` result whose job the store does not have becomes an `error`:
|
|
21
|
+
* the record was lost (a memory store across a restart), and the work may or
|
|
22
|
+
* may not have happened.
|
|
23
|
+
*
|
|
24
|
+
* `settled` is the messages that changed, for the caller to write back, so
|
|
25
|
+
* the store converges and a job settled long ago costs nothing on later loads.
|
|
26
|
+
*
|
|
27
|
+
* `orphans` are jobs whose tool result never reached the thread: the run died
|
|
28
|
+
* between starting the job and storing the result. They are found among the
|
|
29
|
+
* thread's newest jobs, only once the run that started them is gone, and only
|
|
30
|
+
* the ones not marked yet; the caller marks them (`orphaned`).
|
|
31
|
+
*/
|
|
32
|
+
export declare function overlayJobs(messages: AgentMessage[], params: {
|
|
33
|
+
threadId: string;
|
|
34
|
+
store: AgentJobStore;
|
|
35
|
+
isRunLive: (runId: string) => boolean | Promise<boolean>;
|
|
36
|
+
/** The tool's output schema, to check a settled output against. */
|
|
37
|
+
outputSchemaFor?: (toolName: string) => Schema<any> | undefined;
|
|
38
|
+
/** How many of the thread's newest jobs to read. At least 50. */
|
|
39
|
+
scan?: number;
|
|
40
|
+
}): Promise<{
|
|
41
|
+
messages: AgentMessage[];
|
|
42
|
+
settled: AgentMessage[];
|
|
43
|
+
orphans: AgentJobRecord[];
|
|
44
|
+
/** The thread's newest jobs, as they stand after this pass: for the `<jobs>` block. */
|
|
45
|
+
jobs: AgentJobRecord[];
|
|
46
|
+
}>;
|
|
47
|
+
/** Marks orphans found by `overlayJobs`. Never throws: it is bookkeeping. */
|
|
48
|
+
export declare function markOrphans(store: AgentJobStore, orphans: AgentJobRecord[], report: (error: unknown) => void): Promise<void>;
|
|
49
|
+
//# sourceMappingURL=overlay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../../ai/jobs/overlay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,KAAK,EAAe,YAAY,EAAkB,MAAM,UAAU,CAAC;AAE1E,OAAO,KAAK,EAAE,cAAc,EAAiB,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAOpF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,YAAY,EAAE,EACxB,MAAM,EAAE;IACN,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACzD,mEAAmE;IACnE,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IAChE,iEAAiE;IACjE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GACA,OAAO,CAAC;IACT,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,uFAAuF;IACvF,IAAI,EAAE,cAAc,EAAE,CAAC;CACxB,CAAC,CA2DD;AAED,6EAA6E;AAC7E,wBAAsB,WAAW,CAC/B,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,cAAc,EAAE,EACzB,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAC/B,OAAO,CAAC,IAAI,CAAC,CAQf"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../../ai/providers/request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,KAAK,EAAE,YAAY,EAAY,cAAc,EAAoB,MAAM,UAAU,CAAC;AAEzF;;;;;;;GAOG;AAKH,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACzD,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEpD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,MAAM,EAAE,IAAI,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACxB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,IAAI,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IAC3C,SAAS,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,oBAAoB,EAC5B,GAAG,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,oBAAoB,CAAA;CAAE,GACzD,gBAAgB,CAuDlB;AAID;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,YAAY,EAAE,EACxB,YAAY,EAAE,oBAAoB,EAClC,KAAK,CAAC,EAAE,CAAC,gBAAgB,GAAG,qBAAqB,CAAC,EAAE,GACnD,kBAAkB,EAAE,CAmJtB;AA4QD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../../ai/providers/request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,KAAK,EAAE,YAAY,EAAY,cAAc,EAAoB,MAAM,UAAU,CAAC;AAEzF;;;;;;;GAOG;AAKH,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACzD,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEpD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,MAAM,EAAE,IAAI,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACxB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,IAAI,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IAC3C,SAAS,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,oBAAoB,EAC5B,GAAG,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,oBAAoB,CAAA;CAAE,GACzD,gBAAgB,CAuDlB;AAID;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,YAAY,EAAE,EACxB,YAAY,EAAE,oBAAoB,EAClC,KAAK,CAAC,EAAE,CAAC,gBAAgB,GAAG,qBAAqB,CAAC,EAAE,GACnD,kBAAkB,EAAE,CAmJtB;AA4QD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAiC7D;AAuFD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,CAAC,gBAAgB,GAAG,qBAAqB,CAAC,EAAE,GAAG,SAAS,EAC/D,YAAY,EAAE,oBAAoB,GACjC,aAAa,EAAE,CA2CjB"}
|