@qoniai/qoni 0.9.0 → 0.9.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/CHANGELOG.md +62 -0
- package/README.md +132 -38
- package/README.zh-CN.md +121 -34
- package/dist/index.cjs +13842 -492
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25288 -161
- package/dist/index.d.ts +25288 -161
- package/dist/index.js +13840 -492
- package/dist/index.js.map +1 -1
- package/docs/authing-sdk-LICENSE.txt +21 -0
- package/docs/genauth-communication.md +1410 -0
- package/docs/genauth-management-api.md +597 -0
- package/docs/genauth-management.md +285 -0
- package/package.json +14 -5
- package/skills/qoni-sdk/SKILL.md +114 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,67 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Unreleased — GenAuth communication
|
|
4
|
+
|
|
5
|
+
- Add 111 Agent Mail/Phone runtime and administration methods with typed inputs/results.
|
|
6
|
+
- Add native GenAuth credential exchange, bounded polling, idempotency and revision headers, and nested communication error codes.
|
|
7
|
+
- Add bilingual SDK reference content and read-only live acceptance checks; current hosted Phone routes remain unavailable.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## Unreleased
|
|
11
|
+
|
|
12
|
+
- Add 591 GenAuth / Authing v3 management methods across 35 namespaces, aligned with all 496 JSON management methods in the official Authing Node SDK 4.0.2 plus GenAuth extensions and compatibility names. Include typed inputs/results, domain shortcuts and the flat `genauth.management` migration entry.
|
|
13
|
+
- Preserve official SDK defaults and method names; support management PUT operations and safely interpolate DELETE path identifiers. Pin the upstream contract and include its MIT notice.
|
|
14
|
+
- Add `genauth.users.iterate` for streaming paginated user lists and management request cancellation.
|
|
15
|
+
- Coalesce concurrent management-token exchanges, honor JWT expiry and refresh once after automatic-token auth rejection.
|
|
16
|
+
- Surface HTTP-200 GenAuth business errors even with `data`, preserving numeric Authing API codes and request IDs.
|
|
17
|
+
- Preserve the existing user helpers; add generated contract/catalog maintenance, isolated live management acceptance and integration documentation.
|
|
18
|
+
|
|
19
|
+
## Unreleased — next version: 0.10.0
|
|
20
|
+
|
|
21
|
+
These public API changes require **0.10.0**, not a 0.9.x patch. This work does
|
|
22
|
+
not bump the packaged version, publish, or release it.
|
|
23
|
+
|
|
24
|
+
### Breaking
|
|
25
|
+
|
|
26
|
+
- `track.create` requires an explicit schedule. Migrate to an integer
|
|
27
|
+
`{ kind: "interval", intervalSeconds: 600..2592000 }` or an explicit
|
|
28
|
+
`{ kind: "daily", at: "HH:MM", tz }`; daily starts up to 30 minutes early.
|
|
29
|
+
Cron is locally unsupported and is never automatically converted.
|
|
30
|
+
- Interval `tz` and old targetUrls/extractionSchema/triggerDsl/
|
|
31
|
+
stopConditionDsl/notifyChannel/url fields have no wire equivalent. Remove
|
|
32
|
+
them; put watched URLs explicitly in prompt instructions. Optional undefined
|
|
33
|
+
fields are still omitted; defined unsupported fields raise typed local errors.
|
|
34
|
+
- `refine` accepts title/schedule only. Create a new Track to change the original
|
|
35
|
+
prompt/intent; the raw updateMonitor wire API supports explicit instructions.
|
|
36
|
+
- `runNow` returns only `{ trackId, sessionId, runId }`, a 202 acceptance
|
|
37
|
+
reference. TrackTaskRef is a type alias and remains assignable to JsonObject.
|
|
38
|
+
Read the exact recent check for its real `done/failed/expired/canceled`
|
|
39
|
+
status; this differs from RunResult's `succeeded`. Create already starts a
|
|
40
|
+
first look: wait for the original lastTaskId before one explicit runNow.
|
|
41
|
+
- `runs` and `run(id)` search only the newest 50 checks; no extracted/diffs/
|
|
42
|
+
snapshot fields are synthesized. Replace old tick/snapshot consumers with
|
|
43
|
+
the actual check fields; a missing run raises local not_found with its range.
|
|
44
|
+
- Track events/interactionHandle/api.events/api.intervene and DoAnything
|
|
45
|
+
readArtifacts now raise local QoniUnsupportedError with zero HTTP. Their
|
|
46
|
+
deprecated exports remain; use Track checks, separately authorized DoAnything
|
|
47
|
+
interactions, real file artifacts(), or captured screenshot events instead.
|
|
48
|
+
- Pause/delete stop future scheduling and keep an in-flight check running.
|
|
49
|
+
|
|
50
|
+
### Changed
|
|
51
|
+
|
|
52
|
+
- Track now maps supported operations to `/track/tracks`: prompt → instructions,
|
|
53
|
+
explicit integer intervals of 600–2592000 seconds or daily at/tz (starts
|
|
54
|
+
0–30 minutes before target), real status PATCH, empty DELETE204, recent 50
|
|
55
|
+
checks with local pagination, and runNow task references. Refine is limited
|
|
56
|
+
to title/schedule. Deletion does not cancel a running task.
|
|
57
|
+
- Cron, old extraction/DSL/URL/channel options, Track events/intervene and
|
|
58
|
+
interactionHandle fail locally. Deprecated methods/types remain exported.
|
|
59
|
+
- `doAnything.api.readArtifacts` and snapshot types are deprecated with local
|
|
60
|
+
`QoniUnsupportedError` (`unsupported.operation`), zero HTTP. Use actual file
|
|
61
|
+
artifacts or captured screenshot events. File APIs are unchanged.
|
|
62
|
+
- Live coverage metadata retires old monitor/snapshot success claims; current
|
|
63
|
+
Track mapping is locally verified, with live acceptance pending.
|
|
64
|
+
|
|
3
65
|
## 0.9.0 - 2026-10-07
|
|
4
66
|
|
|
5
67
|
DoAnything interactions are now typed by what the user has to do, never by
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
[](https://pnpm.io/)
|
|
6
6
|
[](./LICENSE)
|
|
7
7
|
|
|
8
|
-
Unified Node.js SDK for Qoni Agent delegation, GenAuth
|
|
8
|
+
Unified Node.js SDK for Qoni Agent delegation, GenAuth management, GUMem memory, WebAgent automation, web search, and monitoring.
|
|
9
9
|
|
|
10
10
|
`@qoniai/qoni` gives a trusted server one compact way to use Qoni AK/SK. For runtime product calls, your service verifies the GenAuth user, requests short-lived delegation with `delegateToken`, and then uses the returned token in GUMem, WebAgent, Do Anything, Web Search, and Track calls. For GenAuth user management, the SDK exchanges AK/SK for a standard GenAuth management token internally and calls GenAuth v3 users APIs with that token.
|
|
11
11
|
|
|
@@ -125,6 +125,21 @@ await qoni.genauth.users.update({
|
|
|
125
125
|
// await qoni.genauth.users.deleteBatch({ userIds: [profile.data.userId] });
|
|
126
126
|
```
|
|
127
127
|
|
|
128
|
+
### GenAuth Management
|
|
129
|
+
|
|
130
|
+
`qoni.genauth` exposes **591 typed management methods across 35 namespaces**, aligned with [Authing's official Node SDK 4.0.2](https://github.com/Authing/authing-node-sdk). This includes all 496 official JSON management methods plus GenAuth extensions and compatibility names, including positions, public accounts, invitations, metadata, approvals and risk lists. Calls share the Qoni AK/SK management-token exchange and support cancellation. Deployment features and permissions still determine endpoint availability.
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
await qoni.genauth.groups.create({ code: "engineering", name: "Engineering" });
|
|
134
|
+
await qoni.genauth.groups.addMembers({ code: "engineering", userIds: ["USER_ID"] });
|
|
135
|
+
const roles = await qoni.genauth.management.listRoles({ namespace: "project", page: 1, limit: 20 });
|
|
136
|
+
for await (const user of qoni.genauth.users.iterate({ limit: 50 })) {
|
|
137
|
+
console.log(user.userId);
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
[Integration guide](./docs/genauth-management.md) · [Complete API catalog](./docs/genauth-management-api.md). Roles belong to an existing permission namespace. GenAuth employment and departure rules still apply when deleting users.
|
|
142
|
+
|
|
128
143
|
### Runtime Product Delegation
|
|
129
144
|
|
|
130
145
|
GUMem, WebAgent, Do Anything, Web Search, and Track act for an end user. Silent delegation calls need a real GenAuth user id from the userpool bound to the Qoni credential, then a `delegateToken` result.
|
|
@@ -486,46 +501,104 @@ const followUp = await qoni.deepResearch.run({
|
|
|
486
501
|
});
|
|
487
502
|
```
|
|
488
503
|
|
|
504
|
+
`doAnything.api.readArtifacts()` and the exported `DoAnythingSnapshot`,
|
|
505
|
+
`SnapshotImage`, and `SnapshotAction` types are deprecated. There has never been
|
|
506
|
+
a backend endpoint/source for that structured snapshot contract. The method
|
|
507
|
+
raises local `QoniUnsupportedError` (`code: "unsupported.operation"`) with zero
|
|
508
|
+
HTTP. Use `qoni.doAnything.artifacts({ token, runId })` / `api.listArtifacts()` for files, including
|
|
509
|
+
`artifact.content()` or `api.artifactDownloadUrl()` for downloads. Use
|
|
510
|
+
`capture: { screenshots: true }` and screenshot events for images. A text file
|
|
511
|
+
artifact is not a snapshot; the real file APIs are unchanged.
|
|
512
|
+
|
|
489
513
|
### Track
|
|
490
514
|
|
|
515
|
+
Track uses `/track/tracks`. `prompt` maps to `instructions`; include watched URLs
|
|
516
|
+
in that text. An explicit schedule is required: an integer interval of
|
|
517
|
+
600–2592000 seconds, or a daily time with a time zone. A daily check starts
|
|
518
|
+
0–30 minutes before the target time, rather than exactly at that time.
|
|
519
|
+
|
|
491
520
|
```ts
|
|
521
|
+
import type { MonitorSchedule } from "@qoniai/qoni";
|
|
522
|
+
|
|
492
523
|
const monitor = await qoni.track.create({
|
|
493
524
|
token,
|
|
494
|
-
prompt: "
|
|
495
|
-
|
|
525
|
+
prompt: "Watch https://example.com/policy and report changes.",
|
|
526
|
+
title: "Policy changes",
|
|
527
|
+
schedule: { kind: "interval", intervalSeconds: 3600 },
|
|
528
|
+
}); // create immediately starts a first_look check
|
|
529
|
+
const initial = await monitor.get();
|
|
530
|
+
const firstRunId = initial.lastTaskId; // capture this original ID once
|
|
531
|
+
if (typeof firstRunId !== "string" || !firstRunId) throw new Error("Missing initial lastTaskId");
|
|
532
|
+
const sameMonitor = await qoni.track.attach(monitor.id, { token });
|
|
496
533
|
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
if (status === "active") break;
|
|
534
|
+
async function waitForCheck(runId: string) {
|
|
535
|
+
const deadline = Date.now() + 300_000;
|
|
536
|
+
do {
|
|
537
|
+
const check = await monitor.run(runId); // exact ID in the recent 50 checks
|
|
538
|
+
if (["done", "failed", "expired", "canceled"].includes(String(check.status))) {
|
|
539
|
+
if (check.status !== "done") throw new Error(`Check ${runId} ${String(check.status)}: ${String(check.failure ?? "")}`);
|
|
540
|
+
return check;
|
|
541
|
+
}
|
|
542
|
+
await new Promise(resolve => setTimeout(resolve, Math.min(1000, Math.max(0, deadline - Date.now()))));
|
|
543
|
+
} while (Date.now() < deadline);
|
|
544
|
+
throw new Error(`Check ${runId} timed out`);
|
|
509
545
|
}
|
|
510
546
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
await monitor.
|
|
522
|
-
|
|
523
|
-
await monitor.delete();
|
|
524
|
-
|
|
525
|
-
// Reconnect later from a stored id:
|
|
526
|
-
const sameMonitor = await qoni.track.attach(monitor.id, { token });
|
|
547
|
+
try {
|
|
548
|
+
await monitor.pause(); // pause future scheduling; the first look continues
|
|
549
|
+
await waitForCheck(firstRunId);
|
|
550
|
+
await monitor.refine({ schedule: initial.schedule as MonitorSchedule }); // our known, validated input roundtrips
|
|
551
|
+
await monitor.refine({ schedule: { kind: "daily", at: "09:00", tz: "Asia/Singapore" } });
|
|
552
|
+
const task = await monitor.runNow(); // one explicit manual check while scheduling is paused
|
|
553
|
+
const check = await waitForCheck(task.runId); // 202 acceptance is not completion
|
|
554
|
+
const checks = await monitor.runs({ limit: 10, offset: 0 });
|
|
555
|
+
await monitor.resume();
|
|
556
|
+
} finally {
|
|
557
|
+
await monitor.delete(); // soft-delete; any in-flight check continues
|
|
558
|
+
}
|
|
527
559
|
```
|
|
528
560
|
|
|
561
|
+
Create immediately starts a `first_look` check. Capture its initial `lastTaskId`
|
|
562
|
+
and wait for that same check before one explicit `runNow()`. A concurrent run
|
|
563
|
+
can still cause 409; the SDK surfaces it and never retries. Pause stops future
|
|
564
|
+
scheduled checks and keeps any started check running.
|
|
565
|
+
|
|
566
|
+
Track check `status` is `running`, `done`, `failed`, `expired`, or `canceled`;
|
|
567
|
+
`done` is the successful terminal value. It is kept verbatim and differs from
|
|
568
|
+
one-shot `RunResult.status: "succeeded"`. Known wire schedule shapes are read
|
|
569
|
+
without revalidating server values against SDK write bounds or Intl time zones;
|
|
570
|
+
unknown/incomplete shapes remain verbatim. Writing a schedule stays strict, so
|
|
571
|
+
validate/choose supported input rather than casting every server value back.
|
|
572
|
+
|
|
573
|
+
`runs()` retrieves the backend's newest 50 checks and applies `limit`/`offset`
|
|
574
|
+
locally. `run(id)` searches that same bounded window; a missing ID raises
|
|
575
|
+
`QoniError` with local `code: "not_found"` (no HTTP status) and explains the range. A missing Track itself is the backend 404 `track_not_found`. Checks expose the
|
|
576
|
+
actual status, outcome, headline, answer and failure; no extraction, diffs or
|
|
577
|
+
snapshot IDs are synthesized. `runNow()` can return the backend's 409
|
|
578
|
+
`task_in_progress` while an earlier task is working. It returns a task reference
|
|
579
|
+
on 202; read checks to observe completion.
|
|
580
|
+
|
|
581
|
+
| Retained surface | Current behavior |
|
|
582
|
+
| --- | --- |
|
|
583
|
+
| `track.create`, `track.attach`, `MonitorHandle.get` | Create/read the real Track resource; get converts known wire schedules; unknown shapes stay verbatim. |
|
|
584
|
+
| `MonitorHandle.pause`, `resume` | PATCH `status: paused` / `active`; pause keeps an in-flight check running. |
|
|
585
|
+
| `MonitorHandle.refine` | PATCH title/schedule only; changing prompt/instructions/intent requires a new track. |
|
|
586
|
+
| `MonitorHandle.runNow` | POST `run_now`; returns the actual task reference. |
|
|
587
|
+
| `MonitorHandle.runs`, `run` | Read recent checks with Track read scope only; no DoAnything fallback. |
|
|
588
|
+
| `MonitorHandle.delete` | DELETE 204; soft deletion stops scheduling and does not cancel running work. |
|
|
589
|
+
| `track.api.createMonitor`, `getMonitor` | Historical names retained; use real `instructions`, `title`, and wire schedule `{ every_seconds: N }` or `{ daily_at: "HH:MM", tz }`. |
|
|
590
|
+
| `track.api.updateMonitor` | PATCH real title/instructions/schedule/status fields; wire API permits instructions, while high-level refine does not. |
|
|
591
|
+
| `track.api.runNow`, `deleteMonitor` | Real `run_now` / DELETE; raw task reference / empty 204. |
|
|
592
|
+
| `track.api.listRuns`, `getRun` | Raw checks, local limit/offset, exact lookup within recent 50. |
|
|
593
|
+
| `MonitorHandle.events`, `interactionHandle`, `track.api.events`, `intervene` | Deprecated; no backend endpoint. Local `QoniUnsupportedError`, zero HTTP or token exchange. |
|
|
594
|
+
| `targetUrls`, `extractionSchema`, `triggerDsl`, `stopConditionDsl`, `notifyChannel` (including snake_case aliases), legacy `url` | No backend equivalent; rejected locally with `QoniUnsupportedError`. Put URLs in the prompt explicitly. |
|
|
595
|
+
| Cron schedule | Deprecated and rejected locally with a daily alternative. Arbitrary cron is never silently converted. |
|
|
596
|
+
|
|
597
|
+
A missing schedule, malformed input, invalid interval/time/zone, or invalid
|
|
598
|
+
pagination raises `QoniValidationError` before HTTP. `MonitorSchedule` retains
|
|
599
|
+
the deprecated cron branch; optional undefined fields retain omission behavior, while specified unsupported fields fail; historical event and option types remain exported
|
|
600
|
+
for source compatibility. Unsupported methods are not successful capability tests.
|
|
601
|
+
|
|
529
602
|
### GenAuth User Context and Management
|
|
530
603
|
|
|
531
604
|
```ts
|
|
@@ -632,7 +705,7 @@ interface RunResult {
|
|
|
632
705
|
runId: string;
|
|
633
706
|
status: "succeeded" | "failed" | "canceled"; // delivery status of the run
|
|
634
707
|
output?: unknown; // final answer / payload (shape is task-specific)
|
|
635
|
-
artifacts: Artifact[]; //
|
|
708
|
+
artifacts: Artifact[]; // persisted DoAnything files / deepResearch reports
|
|
636
709
|
isTaskSuccessful?: boolean; // did the task achieve its goal (distinct from `status`)
|
|
637
710
|
terminalReason?: string;
|
|
638
711
|
raw: JsonObject; // full wire envelope — cost, step counts, token usage
|
|
@@ -645,7 +718,7 @@ is the typed payload for that call (e.g. `genauth.users.list` → a paged user
|
|
|
645
718
|
list on `.data`). The exact `T` shapes live in the bundled `.d.ts` and follow
|
|
646
719
|
the backend contract.
|
|
647
720
|
|
|
648
|
-
`MonitorHandle` (Track)
|
|
721
|
+
`MonitorHandle` (Track) provides `id`, `get()`, `pause()`, `resume()`, `refine(patch)`, `runNow()`, `runs()`, `run(runId)`, and `delete()`. Its deprecated `events()` and `interactionHandle()` methods fail locally; see Track above for the complete mapping.
|
|
649
722
|
|
|
650
723
|
### Interactions (HITL)
|
|
651
724
|
|
|
@@ -761,7 +834,7 @@ if (handle.type === InteractionTypes.AskUser && handle.can(ActionKinds.answer))
|
|
|
761
834
|
|
|
762
835
|
### Wire-Level Escape Hatch
|
|
763
836
|
|
|
764
|
-
|
|
837
|
+
Supported low-level methods live under `qoni.<product>.api.*` (e.g. `qoni.doAnything.api.createSession`, `qoni.deepResearch.api.followUp`, `qoni.track.api.createMonitor`). These mirror the backend HTTP contract directly — snake_case fields, double-envelope events, single-ID `/{product}/runs/{run_id}` addressing for run operations — and their shapes may evolve with the API. They are not part of the frozen public contract.
|
|
765
838
|
|
|
766
839
|
`event.raw.event` is the **raw wire event type** — an internal transport name (`run.action.started`, `run.section_completed`, …) whose naming is historical and inconsistent, exposed as a plain string. This is an implementation detail, not the product API: developers match on the curated `event.type` above. The full wire-type catalog is intentionally NOT exported — reach for `event.raw.event` (a string) only when you need an exact wire match the curated layer folds into `progress` (e.g. telling a specific browser action apart).
|
|
767
840
|
|
|
@@ -794,9 +867,9 @@ that type:
|
|
|
794
867
|
// "phase" string — the Deep Research phase name
|
|
795
868
|
// "sectionReady" string — the Deep Research section title
|
|
796
869
|
// "resultsReady" number — Web Search count of unique results
|
|
797
|
-
// "monitorCreated" string —
|
|
798
|
-
// "triggered" string —
|
|
799
|
-
// "checkCompleted" boolean —
|
|
870
|
+
// "monitorCreated" string — deprecated legacy monitor wire type
|
|
871
|
+
// "triggered" string — deprecated legacy monitor wire type
|
|
872
|
+
// "checkCompleted" boolean — deprecated legacy monitor wire type
|
|
800
873
|
// RICH events — event.data is a small object:
|
|
801
874
|
// "message" { text, role }
|
|
802
875
|
// "interaction" the typed Interaction object (HITL) — see Interactions
|
|
@@ -814,7 +887,7 @@ Each product handle is typed to its own subset:
|
|
|
814
887
|
| Do Anything | core: `progress` / `message` / `interaction` / `screenshot` / `browserLiveUrlChanged` / `done` |
|
|
815
888
|
| Web Search | core + `resultsReady` |
|
|
816
889
|
| Deep Research | core + `phase` / `sectionReady` (the outline gate arrives as an `interaction`) |
|
|
817
|
-
| Track (`MonitorHandle`) |
|
|
890
|
+
| Track (`MonitorHandle`) | No SSE endpoint; historical MonitorEvent types are deprecated. Read checks with runs()/run(). |
|
|
818
891
|
|
|
819
892
|
For a live browser preview, listen for `browserLiveUrlChanged` and show
|
|
820
893
|
`event.data.liveUrl` in your viewer. A run can switch browser tabs after its
|
|
@@ -846,6 +919,7 @@ All error classes are exported and can be matched with `instanceof`:
|
|
|
846
919
|
|
|
847
920
|
| Class | Fires when | Typical recovery |
|
|
848
921
|
| --- | --- | --- |
|
|
922
|
+
| `QoniUnsupportedError` | Retained surface has no backend operation (code: `unsupported.operation`); zero HTTP. | Use the alternative named in the error. |
|
|
849
923
|
| `QoniValidationError` | Local input check failed before any request (bad scope string, silent delegation missing a user). | Fix the call — the message states the correct form. |
|
|
850
924
|
| `QoniAuthError` | AK/SK signing rejected by Qoni (bad/rotated credentials). | Check `accessKey` / `secretKey`. |
|
|
851
925
|
| `QoniPermissionDeniedError` | The AccessKey or delegation token lacks a required scope (403). | Check the AccessKey permission policy and request the missing scope with `delegateToken`. |
|
|
@@ -936,3 +1010,23 @@ const artifacts = await client.doAnything.artifacts({ token, runId: run.id });
|
|
|
936
1010
|
```
|
|
937
1011
|
|
|
938
1012
|
Wire methods: `client.doAnything.api.listArtifacts(...)` and `artifactDownloadUrl(...)`.
|
|
1013
|
+
|
|
1014
|
+
## Agent Mail and Agent Phone
|
|
1015
|
+
|
|
1016
|
+
The local GenAuth communication extension provides `qoni.genauth.agentMail` and `qoni.genauth.agentPhone`, including runtime and administrator APIs. Runtime requires native GenAuth credentials via `genauthCommunicationCredentials`; administration reuses Qoni token exchange. See [the communication guide](docs/genauth-communication.md) and [method index](docs/genauth-communication-api.md).
|
|
1017
|
+
|
|
1018
|
+
## Local Agent integration extension
|
|
1019
|
+
|
|
1020
|
+
The integration branch adds `qoni.genauth.auth.createLoginUrl` / `exchangeLoginCode` and
|
|
1021
|
+
`qoni.genauth.agents.create` / `get` / `bind` / `bindUser`, alongside the existing
|
|
1022
|
+
management, Agent Mail and Agent Phone APIs. These additions are not an npm release.
|
|
1023
|
+
The hosted-login callback must validate the App's stored `state` before exchanging
|
|
1024
|
+
the one-use code. Personal mailbox delegation requires a formal IAM `agentId`; an
|
|
1025
|
+
audit label does not prove mailbox ownership. A Personal creation response may still
|
|
1026
|
+
be pending; an unknown result must be reconciled using its original provisioning
|
|
1027
|
+
reference or idempotency key, without starting another creation.
|
|
1028
|
+
|
|
1029
|
+
The Personal Quickstart email creation flow is separate from the unified Agent
|
|
1030
|
+
management model, where identity, email and phone are optional capabilities and an
|
|
1031
|
+
Agent may have multiple email addresses and phone numbers. Personal binding does
|
|
1032
|
+
not issue credentials or enable IAM-token access to the native Mail/Phone APIs.
|
package/README.zh-CN.md
CHANGED
|
@@ -118,6 +118,25 @@ await qoni.genauth.users.update({
|
|
|
118
118
|
// await qoni.genauth.users.deleteBatch({ userIds: [profile.data.userId] });
|
|
119
119
|
```
|
|
120
120
|
|
|
121
|
+
### GenAuth 管理功能
|
|
122
|
+
|
|
123
|
+
`qoni.genauth` 现在提供 **35 个命名空间、591 个管理方法**,以 [Authing 官方 Node SDK 4.0.2](https://github.com/Authing/authing-node-sdk) 为参考,覆盖其全部 496 个 JSON 管理方法,并保留 GenAuth 扩展及兼容名称。除用户、角色、组织、应用和资源授权外,还包括岗位、公共账号、邀请、元数据、审批和风险名单。所有方法复用 Qoni AK/SK 管理 Token 交换,具备 TypeScript 参数及返回类型,并支持取消请求;实际部署的功能开关和权限仍决定接口可用性。
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
await qoni.genauth.groups.create({ code: "engineering", name: "工程团队" });
|
|
127
|
+
await qoni.genauth.groups.addMembers({ code: "engineering", userIds: ["USER_ID"] });
|
|
128
|
+
|
|
129
|
+
// 沿用 Authing v3 方法名称的调用入口:
|
|
130
|
+
const roles = await qoni.genauth.management.listRoles({ namespace: "project", page: 1, limit: 20 });
|
|
131
|
+
|
|
132
|
+
// 自动逐页读取;break 后不会请求下一页:
|
|
133
|
+
for await (const user of qoni.genauth.users.iterate({ limit: 50 })) {
|
|
134
|
+
console.log(user.userId);
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
[使用指南](./docs/genauth-management.md) · [完整 API 清单](./docs/genauth-management-api.md)。角色需属于已存在的权限分组;删除用户仍需遵循 GenAuth 的在职与离职规则。
|
|
139
|
+
|
|
121
140
|
### 运行时产品委托
|
|
122
141
|
|
|
123
142
|
GUMem、WebAgent、Do Anything、Web Search、Track 是代表终端用户执行的运行时产品能力。silent 委托需要一个来自 Qoni credential 绑定 userpool 的真实 GenAuth 用户 ID,再使用 `delegateToken` 返回的 token。
|
|
@@ -453,43 +472,93 @@ const followUp = await qoni.deepResearch.run({
|
|
|
453
472
|
});
|
|
454
473
|
```
|
|
455
474
|
|
|
475
|
+
`doAnything.api.readArtifacts()` 及导出类型 `DoAnythingSnapshot`、`SnapshotImage`、
|
|
476
|
+
`SnapshotAction` 已 deprecated:该结构化快照契约从未有后端路径或字段来源。
|
|
477
|
+
方法本地抛 `QoniUnsupportedError(code: "unsupported.operation")`,零 HTTP。
|
|
478
|
+
文件请用 `qoni.doAnything.artifacts({ token, runId })` / `api.listArtifacts()`,下载用 `artifact.content()` /
|
|
479
|
+
`api.artifactDownloadUrl()`;图片请开启 `capture: { screenshots: true }` 并读取
|
|
480
|
+
screenshot events。文本文件不是 snapshot,真实文件 artifacts API 保持。
|
|
481
|
+
|
|
456
482
|
### Track
|
|
457
483
|
|
|
484
|
+
Track 使用真实 `/track/tracks`。`prompt` 原样映射到 `instructions`,目标 URL
|
|
485
|
+
请明确写在描述中。必须显式指定 schedule:整数 600–2592000 秒 interval,或带
|
|
486
|
+
时区的 daily。daily 在目标时间前 0–30 分钟启动,不保证整点启动。
|
|
487
|
+
|
|
458
488
|
```ts
|
|
489
|
+
import type { MonitorSchedule } from "@qoniai/qoni";
|
|
490
|
+
|
|
459
491
|
const monitor = await qoni.track.create({
|
|
460
492
|
token,
|
|
461
|
-
prompt: "
|
|
462
|
-
|
|
493
|
+
prompt: "监控 https://example.com/policy 并报告变化。",
|
|
494
|
+
title: "政策变化",
|
|
495
|
+
schedule: { kind: "interval", intervalSeconds: 3600 },
|
|
496
|
+
}); // create 立即启动 first_look 首次检查
|
|
497
|
+
const initial = await monitor.get();
|
|
498
|
+
const firstRunId = initial.lastTaskId; // 只捕获一次原始首检 ID
|
|
499
|
+
if (typeof firstRunId !== "string" || !firstRunId) throw new Error("缺少初始 lastTaskId");
|
|
500
|
+
const sameMonitor = await qoni.track.attach(monitor.id, { token });
|
|
463
501
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
502
|
+
async function waitForCheck(runId: string) {
|
|
503
|
+
const deadline = Date.now() + 300_000;
|
|
504
|
+
do {
|
|
505
|
+
const check = await monitor.run(runId); // 在最近 50 条中按原始 ID 精确查找
|
|
506
|
+
if (["done", "failed", "expired", "canceled"].includes(String(check.status))) {
|
|
507
|
+
if (check.status !== "done") throw new Error(`检查 ${runId} ${String(check.status)}:${String(check.failure ?? "")}`);
|
|
508
|
+
return check;
|
|
509
|
+
}
|
|
510
|
+
await new Promise(resolve => setTimeout(resolve, Math.min(1000, Math.max(0, deadline - Date.now()))));
|
|
511
|
+
} while (Date.now() < deadline);
|
|
512
|
+
throw new Error(`检查 ${runId} 超时`);
|
|
475
513
|
}
|
|
476
514
|
|
|
477
|
-
|
|
478
|
-
|
|
515
|
+
try {
|
|
516
|
+
await monitor.pause(); // 停止未来调度,已经启动的首检继续
|
|
517
|
+
await waitForCheck(firstRunId);
|
|
518
|
+
await monitor.refine({ schedule: initial.schedule as MonitorSchedule }); // 本次已校验的已知输入可 roundtrip
|
|
519
|
+
await monitor.refine({ schedule: { kind: "daily", at: "09:00", tz: "Asia/Singapore" } });
|
|
520
|
+
const task = await monitor.runNow(); // 调度暂停时,显式手动执行一次
|
|
521
|
+
const check = await waitForCheck(task.runId); // 202 接受不等于完成
|
|
522
|
+
const checks = await monitor.runs({ limit: 10, offset: 0 });
|
|
523
|
+
await monitor.resume();
|
|
524
|
+
} finally {
|
|
525
|
+
await monitor.delete(); // 软删除;仍在运行的检查继续
|
|
526
|
+
}
|
|
527
|
+
```
|
|
479
528
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
// get()/run() 读回时,抽取字段名与抽取结果保留原始键名。
|
|
484
|
-
// 自然语言意图不可 refine——要改描述请新建 monitor:
|
|
485
|
-
await monitor.refine({ schedule: { kind: "cron", expr: "0 9 * * *" } });
|
|
486
|
-
await monitor.pause(); // 停掉定时 tick 但不删除
|
|
487
|
-
await monitor.resume();
|
|
488
|
-
await monitor.delete();
|
|
529
|
+
create 会立即启动一次 `first_look` 首检。只捕获一次初始 `lastTaskId`,等待
|
|
530
|
+
同一个首检结束,再显式调用一次 runNow。并发启动其他任务仍可能导致 409,SDK
|
|
531
|
+
原样抛出,不隐式重试。pause 只暂停未来调度,已经启动的检查继续。
|
|
489
532
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
533
|
+
Track check.status 为 `running/done/failed/expired/canceled`,成功终态是 **done**,
|
|
534
|
+
原样保留,区别于单次 RunResult.status 的 succeeded。读回已知 wire schedule 形状
|
|
535
|
+
时不重新套用 SDK 写入边界或 Intl 时区校验;未知/不完整形状原样保留。写入仍严格
|
|
536
|
+
校验,请选择支持的输入,不要把任意服务端 schedule 强制 cast 后重写。
|
|
537
|
+
|
|
538
|
+
`runs()` 查询后端最近 50 条 checks,再在本地应用 limit/offset;`run(id)` 只在
|
|
539
|
+
同一窗口按精确 run_id 查找,未找到抛本地 `QoniError(code: "not_found")`(没有 HTTP status)并说明范围;Track 本身不存在是后端 404 `track_not_found`。
|
|
540
|
+
检查保留真实 status/outcome/headline/answer/failure,不补造 extracted、diffs 或
|
|
541
|
+
snapshotId。早前任务仍在运行时,`runNow()` 会原样抛后端 409 `task_in_progress`;
|
|
542
|
+
成功只返回真实任务引用,完成与否需要再读 checks。
|
|
543
|
+
|
|
544
|
+
| 保留的方法或输入 | 当前行为 |
|
|
545
|
+
| --- | --- |
|
|
546
|
+
| `track.create`、`attach`、`MonitorHandle.get` | 创建/读取真实 Track;get 转换已知 schedule 形状,未知形状原样保留。 |
|
|
547
|
+
| `MonitorHandle.pause`、`resume` | PATCH status 为 paused / active;pause 不停已启动的检查。 |
|
|
548
|
+
| `MonitorHandle.refine` | 仅修改 title/schedule;改 prompt/instructions/intent 需新建 Track。 |
|
|
549
|
+
| `MonitorHandle.runNow` | POST run_now,返回真实任务引用。 |
|
|
550
|
+
| `MonitorHandle.runs`、`run` | 仅以 Track read scope 读取最近检查,不回退到 DoAnything。 |
|
|
551
|
+
| `MonitorHandle.delete` | DELETE204 软删除停止调度,不取消正在运行的任务。 |
|
|
552
|
+
| `track.api.createMonitor`、`getMonitor` | 保留旧方法名;真实字段为 instructions/title,wire schedule 为 `{ every_seconds: N }` 或 `{ daily_at: "HH:MM", tz }`。 |
|
|
553
|
+
| `track.api.updateMonitor` | PATCH 真实 title/instructions/schedule/status;低层可改 instructions,高层 refine 不允许。 |
|
|
554
|
+
| `track.api.runNow`、`deleteMonitor` | 真实 run_now / DELETE;wire 任务引用 / 空 204。 |
|
|
555
|
+
| `track.api.listRuns`、`getRun` | 原始 checks,本地分页,精确查找最近 50 条。 |
|
|
556
|
+
| `MonitorHandle.events`、`interactionHandle`、`track.api.events`、`intervene` | deprecated,无后端路径,本地 QoniUnsupportedError,零 HTTP/零 token exchange。 |
|
|
557
|
+
| `targetUrls`、`extractionSchema`、`triggerDsl`、`stopConditionDsl`、`notifyChannel`(含 snake_case 别名)、旧 `url` | 无对应字段,本地 QoniUnsupportedError;URL 需明确写入 prompt。 |
|
|
558
|
+
| cron schedule | deprecated,本地明确拒绝并给出 daily 替代,不默默转换任意 cron。 |
|
|
559
|
+
|
|
560
|
+
无 schedule、非法 interval/时间/时区/分页等输入在 HTTP 前抛 `QoniValidationError`。
|
|
561
|
+
旧类型导出与 cron 分支保留并标记 deprecated;值为 undefined 的可选键保持省略行为,有值的不支持字段仍拒绝;unsupported 负例不算能力正例。
|
|
493
562
|
|
|
494
563
|
### GenAuth 用户上下文与用户管理
|
|
495
564
|
|
|
@@ -582,7 +651,7 @@ interface RunResult {
|
|
|
582
651
|
runId: string;
|
|
583
652
|
status: "succeeded" | "failed" | "canceled"; // run 的交付状态
|
|
584
653
|
output?: unknown; // 最终答案 / 载荷(形状随任务而定)
|
|
585
|
-
artifacts: Artifact[]; //
|
|
654
|
+
artifacts: Artifact[]; // 持久化 DoAnything 文件 / deepResearch 报告
|
|
586
655
|
isTaskSuccessful?: boolean; // 任务是否达成目标(与 status 不同)
|
|
587
656
|
terminalReason?: string;
|
|
588
657
|
raw: JsonObject; // 完整 wire envelope——成本、步数、token 用量
|
|
@@ -591,7 +660,7 @@ interface RunResult {
|
|
|
591
660
|
|
|
592
661
|
每个 `Artifact` 暴露 `id`、`name?`、`mime?`、`sizeBytes?`、`createdAt?` 和 `content(): Promise<Uint8Array>`(懒加载字节)。其余方法都返回下文的 `QoniResponse<T>` 信封,`T` 是该调用的具体载荷类型(例如 `genauth.users.list` → `.data` 上的分页用户列表)。`T` 的精确形状见随包的 `.d.ts`,与后端契约一致。
|
|
593
662
|
|
|
594
|
-
`MonitorHandle`(Track)提供 `id`、`get()`、`pause()`、`resume()`、`refine(patch)`、`runNow()`、`
|
|
663
|
+
`MonitorHandle`(Track)提供 `id`、`get()`、`pause()`、`resume()`、`refine(patch)`、`runNow()`、`runs()`、`run(runId)`、`delete()`。deprecated 的 `events()` / `interactionHandle()` 本地拒绝,完整逐项映射见上方 Track。
|
|
595
664
|
|
|
596
665
|
### 交互(HITL)
|
|
597
666
|
|
|
@@ -663,7 +732,7 @@ if (handle.type === InteractionTypes.AskUser && handle.can(ActionKinds.answer))
|
|
|
663
732
|
|
|
664
733
|
### Wire 级逃生舱
|
|
665
734
|
|
|
666
|
-
|
|
735
|
+
可支持的低层方法保留在 `qoni.<product>.api.*` 下(如 `qoni.doAnything.api.createSession`、`qoni.deepResearch.api.followUp`、`qoni.track.api.createMonitor`)。这些方法直接镜像 wire 形状——snake_case 字段、双层 envelope 事件、run 操作统一走 `/{product}/runs/{run_id}` 单 ID 寻址——形状会随 API 演进变化,不在冻结的公开契约范围内。
|
|
667
736
|
|
|
668
737
|
原始 wire 事件类型(`run.action.started` 这种内部传输名,命名是历史遗留、也不一致)**不作为公开导出**——开发者按上面那套精选 `event.type` 匹配即可;极少数要精确 wire 的场景,`event.raw.event` 是个原始字符串,直接比对。
|
|
669
738
|
|
|
@@ -694,9 +763,9 @@ type QoniResponse<T> = {
|
|
|
694
763
|
// "phase" string —— Deep Research 阶段名
|
|
695
764
|
// "sectionReady" string —— Deep Research 章节标题
|
|
696
765
|
// "resultsReady" number —— Web Search 结果数
|
|
697
|
-
// "monitorCreated" string ——
|
|
698
|
-
// "triggered" string ——
|
|
699
|
-
// "checkCompleted" boolean ——
|
|
766
|
+
// "monitorCreated" string —— deprecated 的旧 monitor wire 类型
|
|
767
|
+
// "triggered" string —— deprecated 的旧 monitor wire 类型
|
|
768
|
+
// "checkCompleted" boolean —— deprecated 的旧 monitor wire 类型
|
|
700
769
|
// 丰富事件 —— event.data 是个小对象:
|
|
701
770
|
// "message" { text, role }
|
|
702
771
|
// "interaction" 带类型的 Interaction 对象(HITL)—— 见「交互」一节
|
|
@@ -713,7 +782,7 @@ type QoniResponse<T> = {
|
|
|
713
782
|
| Do Anything | 核心:`progress` / `message` / `interaction` / `screenshot` / `browserLiveUrlChanged` / `done` |
|
|
714
783
|
| Web Search | 核心 + `resultsReady` |
|
|
715
784
|
| Deep Research | 核心 + `phase` / `sectionReady`(大纲审批走 `interaction`) |
|
|
716
|
-
| Track(`MonitorHandle`) |
|
|
785
|
+
| Track(`MonitorHandle`) | 无 SSE 路径,旧 MonitorEvent 类型 deprecated;用 runs()/run() 读取检查。 |
|
|
717
786
|
|
|
718
787
|
展示实时浏览器时,监听 `browserLiveUrlChanged`,用 `event.data.liveUrl` 更新预览地址。任务执行期间可能切换标签页,因此不能只使用第一次收到的地址。`forceViewerReload` 为 true 时重载已有预览。live URL 可访问浏览器画面,不要写入公开日志。
|
|
719
788
|
|
|
@@ -739,6 +808,7 @@ type QoniEvent<T = unknown> = {
|
|
|
739
808
|
|
|
740
809
|
| 类 | 触发时机 | 典型处理 |
|
|
741
810
|
| --- | --- | --- |
|
|
811
|
+
| `QoniUnsupportedError` | 保留表面没有后端操作(code: `unsupported.operation`),零 HTTP。 | 使用错误提示中的真实替代能力。 |
|
|
742
812
|
| `QoniValidationError` | 请求发出前的本地校验失败(scope 字符串格式错、silent 委托缺 user)。 | 按消息修正调用——消息里给出正确写法。 |
|
|
743
813
|
| `QoniAuthError` | AK/SK 签名被 Qoni 拒绝(凭据错误/已轮换)。 | 检查 `accessKey` / `secretKey`。 |
|
|
744
814
|
| `QoniPermissionDeniedError` | AccessKey 或 delegation token 缺少所需 scope(403)。 | 检查 AccessKey 权限策略,并在 `delegateToken` 中申请所需 scope。 |
|
|
@@ -827,3 +897,20 @@ const artifacts = await client.doAnything.artifacts({ token, runId: run.id });
|
|
|
827
897
|
```
|
|
828
898
|
|
|
829
899
|
Wire methods: `client.doAnything.api.listArtifacts(...)` and `artifactDownloadUrl(...)`.
|
|
900
|
+
|
|
901
|
+
## Agent Mail 与 Agent Phone
|
|
902
|
+
|
|
903
|
+
本地通信扩展提供 `qoni.genauth.agentMail` 和 `qoni.genauth.agentPhone` 的运行侧与管理侧 API。运行侧通过 `genauthCommunicationCredentials` 配置原生 GenAuth 凭据;管理侧复用 Qoni 的兑换流程。详见 [通信指南](docs/genauth-communication.md) 与 [方法索引](docs/genauth-communication-api.md)。
|
|
904
|
+
|
|
905
|
+
## 本地 Agent 整合扩展
|
|
906
|
+
|
|
907
|
+
整合分支增加 `qoni.genauth.auth.createLoginUrl` / `exchangeLoginCode` 与
|
|
908
|
+
`qoni.genauth.agents.create` / `get` / `bind` / `bindUser`,并保留原有管理、
|
|
909
|
+
Agent Mail 和 Agent Phone 接口。这些新增内容尚未发布到 npm。登录回调必须先核对
|
|
910
|
+
App 保存的 `state`,再兑换一次性 code。Personal 邮箱委托必须指定真实 IAM
|
|
911
|
+
`agentId`,审计标签不能证明邮箱归属。创建可能仍处于 pending;结果未知时只能使用
|
|
912
|
+
原 provisioning 引用或幂等键核对,不能重新创建资源。
|
|
913
|
+
|
|
914
|
+
Personal Quickstart 的邮箱创建流程与统一 Agent 管理的可选能力模型分别保留。
|
|
915
|
+
统一管理中身份、邮箱、手机号均可选,一个 Agent 可以拥有多个邮箱和手机号。
|
|
916
|
+
绑定 Personal 身份不会签发凭据,也不会自动打通 IAM token 调用原生 Mail/Phone API。
|