@anchrd/intel-api 0.14.0 → 0.16.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.
Files changed (60) hide show
  1. package/dist/adapters/cloudflare/cloudflare.js +0 -68
  2. package/dist/adapters/cloudflare/cloudflare.types.d.ts +0 -39
  3. package/dist/adapters/db/db-flows.js +3 -2
  4. package/dist/adapters/db/db-grants.d.ts +1 -1
  5. package/dist/adapters/db/db-grants.js +1 -1
  6. package/dist/adapters/db/db.js +16 -113
  7. package/dist/adapters/openid/openid.js +1 -1
  8. package/dist/adapters/remote-tools/remote-tools.js +1 -1
  9. package/dist/bundle/bundle.js +31 -141
  10. package/dist/bundle/bundle.types.d.ts +1 -1
  11. package/dist/cli/cli.js +18 -11
  12. package/dist/flows/flows.d.ts +1 -1
  13. package/dist/flows/flows.js +1 -1
  14. package/dist/flows/flows.types.d.ts +4 -1
  15. package/dist/http/http.js +43 -238
  16. package/dist/http/http.types.d.ts +0 -8
  17. package/dist/indexing/indexing.js +18 -89
  18. package/dist/intel/intel.js +4 -9
  19. package/dist/intel/intel.types.d.ts +0 -6
  20. package/dist/mcp/mcp.js +84 -361
  21. package/dist/mcp/mcp.types.d.ts +2 -7
  22. package/dist/nodes/document-links/document-links.d.ts +6 -8
  23. package/dist/nodes/document-links/document-links.js +8 -31
  24. package/dist/nodes/nodes.js +24 -890
  25. package/dist/nodes/nodes.types.d.ts +14 -173
  26. package/dist/tools/tool-servers/tool-servers.d.ts +1 -1
  27. package/dist/tools/tool-servers/tool-servers.js +1 -1
  28. package/dist/tools/tools.js +37 -148
  29. package/dist/tools/tools.types.d.ts +1 -22
  30. package/migrations/0018_no_context_policy_at_last.sql +13 -6
  31. package/migrations/0019_one_name_for_the_grants.sql +52 -0
  32. package/package.json +2 -2
  33. package/dist/adapters/cloudflare-api/cloudflare-api.d.ts +0 -22
  34. package/dist/adapters/cloudflare-api/cloudflare-api.js +0 -306
  35. package/dist/adapters/cloudflare-api/cloudflare-api.types.d.ts +0 -64
  36. package/dist/adapters/cloudflare-api/cloudflare-api.types.js +0 -1
  37. package/dist/adapters/gate-applications/gate-applications.d.ts +0 -23
  38. package/dist/adapters/gate-applications/gate-applications.js +0 -88
  39. package/dist/adapters/tool-delegation/tool-delegation.d.ts +0 -22
  40. package/dist/adapters/tool-delegation/tool-delegation.js +0 -90
  41. package/dist/agent-costs/agent-costs.d.ts +0 -16
  42. package/dist/agent-costs/agent-costs.js +0 -105
  43. package/dist/agent-costs/agent-costs.types.d.ts +0 -30
  44. package/dist/agent-costs/agent-costs.types.js +0 -1
  45. package/dist/agent-runtime/agent-runtime.d.ts +0 -16
  46. package/dist/agent-runtime/agent-runtime.js +0 -150
  47. package/dist/agent-runtime/agent-runtime.types.d.ts +0 -122
  48. package/dist/agent-runtime/agent-runtime.types.js +0 -1
  49. package/dist/model-catalog/model-catalog.d.ts +0 -2
  50. package/dist/model-catalog/model-catalog.js +0 -99
  51. package/dist/model-catalog/model-catalog.types.d.ts +0 -15
  52. package/dist/model-catalog/model-catalog.types.js +0 -1
  53. package/dist/nodes/board/board.d.ts +0 -61
  54. package/dist/nodes/board/board.js +0 -826
  55. package/dist/nodes/board/board.types.d.ts +0 -38
  56. package/dist/nodes/board/board.types.js +0 -1
  57. package/migrations/0013_agents_in_the_tree.sql +0 -76
  58. package/migrations/0014_agent_applications.sql +0 -25
  59. package/migrations/0015_tools_delegated_from_a_connection.sql +0 -15
  60. package/migrations/0016_boards_in_the_tree.sql +0 -80
@@ -1,6 +1,8 @@
1
- import { AgentDefinition, AgentMediaType, BlockNoteMediaType, BoardDocument, BoardMediaType, BundleImportResult, BundleManifest, BundleManifestFilename, DocumentLinkInlineType, FlowGraph, TableMediaType, } from "@anchrd/intel-contract";
1
+ import { BundleImportResult, BundleManifest, BundleManifestFilename, } from "@anchrd/intel-contract/bundle";
2
+ import { FlowGraph } from "@anchrd/intel-contract/flow";
3
+ import { BlockNoteMediaType, DocumentLinkInlineType, } from "@anchrd/intel-contract/node";
4
+ import { TableMediaType } from "@anchrd/intel-contract/table";
2
5
  import { Unzip, UnzipInflate, Zip, ZipDeflate, ZipPassThrough } from "fflate";
3
- import { repeatedBoardId, upgradeStoredBoard } from "../nodes/board/board.js";
4
6
  import { documentLinkTargets } from "../nodes/document-links/document-links.js";
5
7
  import { parseCsv } from "../shared/csv/csv.js";
6
8
  import { IntelError } from "../shared/intel-error/intel-error.js";
@@ -217,13 +219,11 @@ function nakedKindOf(name) {
217
219
  if (lower.endsWith(".csv")) {
218
220
  return { kind: "table", mediaType: TableMediaType, title: name.slice(0, -4) };
219
221
  }
220
- // ⚠️ Before any plain `.json` rule and with a compound suffix on purpose (#285). A board is not
221
- // recognisable from `.json` alone an agent definition wears the same extension — so the export
222
- // writes `.board.json` and a naked upload has to spell it out too. A file that only says `.json`
223
- // is an attachment, which is what it was before boards existed.
224
- if (lower.endsWith(".board.json")) {
225
- return { kind: "board", mediaType: BoardMediaType, title: name.slice(0, -11) };
226
- }
222
+ // ⚠️ `.board.json` had its own rule here until #390 and deliberately does not any more. This is
223
+ // the NAKED-folder patha directory somebody picked, with no manifest — so a file called
224
+ // `plan.board.json` is a JSON file on a disk, and keeping it as an attachment preserves it. A
225
+ // real export is a different matter: its manifest declares the kind, and that is where such an
226
+ // entry is refused by name.
227
227
  return { kind: "attachment", mediaType: guessedMediaType(lower), title: name };
228
228
  }
229
229
  const KnownMediaTypes = {
@@ -402,41 +402,11 @@ export function createBundle(deps) {
402
402
  },
403
403
  };
404
404
  }
405
- // A board is one JSON file, exactly like an agent's definition: the document IS the board, so
406
- // there is nothing to serialize differently for an export (#285). A board with no version yet
407
- // exports as an empty file, the same way an agent without a definition does.
408
- if (node.kind === "board") {
409
- const path = `${directory}${uniqueName(used, base, ".board.json")}`;
410
- return {
411
- manifest: {
412
- id: node.id,
413
- kind: "board",
414
- title: node.title,
415
- description: node.description,
416
- mediaType: version?.mediaType ?? BoardMediaType,
417
- path,
418
- },
419
- content: version === null
420
- ? { type: "text", load: async () => "" }
421
- : { type: "text", load: textLoader(version.contentKey) },
422
- };
423
- }
424
- if (node.kind === "agent") {
425
- const path = `${directory}${uniqueName(used, base, ".json")}`;
426
- return {
427
- manifest: {
428
- id: node.id,
429
- kind: "agent",
430
- title: node.title,
431
- description: node.description,
432
- mediaType: version?.mediaType ?? "application/json",
433
- path,
434
- },
435
- content: version === null
436
- ? { type: "text", load: async () => "" }
437
- : { type: "text", load: textLoader(version.contentKey) },
438
- };
439
- }
405
+ // ⚠️ A row of a kind this build no longer makes — an `agent` or a `board` written before #390
406
+ // falls through to the document branch and travels as its raw body. Deliberately forgiving:
407
+ // refusing here would make one leftover row enough to stop a whole subtree from being exported,
408
+ // and the file it produces is exactly the bytes that were stored. The IMPORT is where such a
409
+ // bundle is turned away, by name.
440
410
  // A document: markdown stays `.md`, a BlockNote body is JSON and says so with its name.
441
411
  const mediaType = version?.mediaType ?? "text/markdown";
442
412
  const extension = mediaType === BlockNoteMediaType ? ".json" : ".md";
@@ -945,103 +915,23 @@ export function createBundle(deps) {
945
915
  version = versionRowFor(entry, text, TableMediaType, await deps.hash(text), "snapshot");
946
916
  }
947
917
  }
948
- else if (entry.kind === "board") {
949
- const text = entry.body === null ? "" : decodeText(entry.body, entry.path);
950
- if (text.trim().length > 0) {
951
- let document;
952
- try {
953
- // Same upgrade the stored read does (anchrd/intel#311): a bundle exported before
954
- // `terminal` existed is exactly an old board in a file, and importing it must not be
955
- // the one way to lose a board.
956
- document = BoardDocument.parse(upgradeStoredBoard(JSON.parse(text)));
957
- }
958
- catch {
959
- throw new IntelError(400, "import_invalid_board", `Bundle entry is not a board: ${entry.path}`);
960
- }
961
- /**
962
- * ⚠️ Refused by name, and refused rather than folded (anchrd/intel#321).
963
- *
964
- * A board arriving in a file is the ONE place a document somebody else wrote becomes
965
- * truth here — everywhere else a task id is minted by `deps.id()` and a status list
966
- * goes through `ConfigureBoardInput`, which has demanded distinct ids since #285. Two
967
- * tasks under one id threw `graph.addNode` out of the board's graph view, and two
968
- * statuses under one id drew the same cards in two lanes with a drop that had two
969
- * targets meaning one.
970
- *
971
- * Outside the catch above on purpose: swallowed into `import_invalid_board` this would
972
- * read as "that file is not a board", and whoever is holding the file would look for
973
- * the wrong thing. `repeatedBoardId` names the id, which is the line they have to fix.
974
- *
975
- * ⚠️ And it names the way out, not only the fault (anchrd/intel#341). The usual holder
976
- * of such a file is not its author but somebody moving a tree between installations,
977
- * and the pair is in the BOARD the export came from — where `board_repair_task_ids`
978
- * and `board_configure` each remove one kind of it. Told only what is wrong, they were
979
- * left editing JSON by hand or leaving the board behind, and an import is all or
980
- * nothing: one such board stops the whole move.
981
- */
982
- const repeated = repeatedBoardId(document);
983
- if (repeated !== null) {
984
- throw new IntelError(400, "import_duplicate_board_id", repeated.list === "tasks"
985
- ? `Bundle entry names the task “${repeated.id}” twice: ${entry.path}. Repair that board with board_repair_task_ids where it came from, then export it again.`
986
- : `Bundle entry names the status “${repeated.id}” twice: ${entry.path}. Repair that board with board_configure — the status list written whole, with distinct ids — where it came from, then export it again.`);
987
- }
988
- // ⚠️ `references` are remapped the way a document's inline links are, and `dependsOn`
989
- // and `parentId` are NOT (#285). A task's references point at NODES, which the import
990
- // renumbers; its dependencies and its parent point at tasks inside this very file,
991
- // whose ids the import does not touch. Renumbering those would break every edge in the
992
- // board for no reason.
993
- const remapped = {
994
- statuses: document.statuses,
995
- tasks: document.tasks.map((task) => ({
996
- ...task,
997
- references: task.references.map((reference) => idMap.get(reference) ?? reference),
998
- })),
999
- };
1000
- const body = JSON.stringify(remapped);
1001
- version = versionRowFor(entry, body, BoardMediaType, await deps.hash(body), null);
1002
- // Into the same link pass as an imported document: a board's references are `text`
1003
- // links, so they have to survive the import the same way.
1004
- documentBodies.set(entry.newId, { mediaType: BoardMediaType, content: body });
1005
- }
1006
- }
1007
- else if (entry.kind === "agent") {
1008
- const text = entry.body === null ? "" : decodeText(entry.body, entry.path);
1009
- if (text.trim().length > 0) {
1010
- let definition;
1011
- try {
1012
- definition = AgentDefinition.parse(JSON.parse(text));
1013
- }
1014
- catch {
1015
- throw new IntelError(400, "import_invalid_agent", `Bundle entry is not an agent definition: ${entry.path}`);
1016
- }
1017
- const remapped = {
1018
- ...definition,
1019
- /**
1020
- * ⚠️ A delegation NEVER travels in a file (#208, D30). `tools.delegatedBy` names
1021
- * whose portal connection an agent acts on, and the only thing that may write it is
1022
- * a person saving the agent in a session Intel authorized — the save path proves
1023
- * they reach every named server first. A bundle is a document somebody hands over;
1024
- * carrying the field through would let a crafted file name a local user and hand an
1025
- * imported agent that person's connection, with no act of theirs anywhere.
1026
- *
1027
- * The consequence is deliberate and mild: an imported agent arrives with no tools,
1028
- * and whoever wants it to have some gives them in the profile — which is the same
1029
- * act D30 made the only way in.
1030
- */
1031
- tools: null,
1032
- references: definition.references.map((reference) => idMap.has(reference.nodeId)
1033
- ? { ...reference, nodeId: idMap.get(reference.nodeId) }
1034
- : reference),
1035
- schedules: definition.schedules.map((schedule) => idMap.has(schedule.target.id)
1036
- ? {
1037
- ...schedule,
1038
- target: { ...schedule.target, id: idMap.get(schedule.target.id) },
1039
- }
1040
- : schedule),
1041
- };
1042
- const body = JSON.stringify(remapped);
1043
- version = versionRowFor(entry, body, AgentMediaType, await deps.hash(body), null);
1044
- }
918
+ else if (entry.kind === "board" || entry.kind === "agent") {
919
+ /**
920
+ * ⚠️ Refused by name, and the name says WHY rather than what the parser tripped over.
921
+ *
922
+ * Agents and Boards were parked with #385; nothing in this build can hold either kind.
923
+ * A bundle that carries one is not malformed — it is a correct export of an installation
924
+ * that still had the feature, and the person holding it is usually moving a tree between
925
+ * two installations rather than the author of the file. Left to the schema they would get
926
+ * `unexpected enum value`, look for a broken file, and find nothing wrong with it.
927
+ *
928
+ * The refusal names the entry, the kind and the branch the feature is parked on, so the
929
+ * answer to "where did my board go" is in the message and not in somebody's memory.
930
+ *
931
+ * ⚠️ Only a MANIFEST can reach this, because only a manifest declares a kind. A naked
932
+ * folder holding a `plan.board.json` imports it as an attachment — see `kindOfFile`.
933
+ */
934
+ throw new IntelError(400, "import_kind_parked", `Bundle entry “${entry.path}” is a ${entry.kind}, and ${entry.kind}s are not part of this installation any more (anchrd/intel#385). The bundle was exported from a version that still had them; the code is on the branch parked/agents-and-board. Remove the entry from the bundle to import the rest.`);
1045
935
  }
1046
936
  else if (entry.kind === "attachment") {
1047
937
  const bytes = entry.body ?? new Uint8Array(0);
@@ -1,4 +1,4 @@
1
- import type { BundleImportResult, BundleManifest } from "@anchrd/intel-contract";
1
+ import type { BundleImportResult, BundleManifest } from "@anchrd/intel-contract/bundle";
2
2
  import type { FlowRepository } from "../flows/flows.types.js";
3
3
  import type { Actor, ContentStore, NodeRepository } from "../nodes/nodes.types.js";
4
4
  export interface BundleActor extends Actor {
package/dist/cli/cli.js CHANGED
@@ -2,7 +2,20 @@ import { createBuild } from "../build/build.js";
2
2
  import { createPrepare } from "../prepare/prepare.js";
3
3
  const interfaces = [
4
4
  { handle: "intel", functions: ["use", "admin"] },
5
- { handle: "knowledge", functions: ["read", "create", "write", "share"] },
5
+ // ⚠️ `nodes`, not `knowledge` and the rename cost something, which is why it needed its own
6
+ // ticket (#152) five months after #125 renamed everything else. This handle is only half Intel's:
7
+ // `bootstrap` DECLARES it in Gate and deliberately changes no grant, so to Gate a renamed handle
8
+ // is a NEW one. Every grant on the old name keeps pointing at the old name, and everybody loses
9
+ // access at once, silently, until an operator hands the permissions out again.
10
+ //
11
+ // It was done in the one window where that is free: the installation on anchrd.sh was being
12
+ // rebuilt anyway (#385, anchrd/core#93) and there is no other. Doing it later would mean doing it
13
+ // to somebody.
14
+ //
15
+ // ⚠️ The old `knowledge` interface stays declared in Gate — bootstrap declares, it never revokes.
16
+ // It is a harmless leftover on installations that have it, and nothing in Intel asks about it any
17
+ // more; removing it is an act in Gate, by hand, when somebody is sure nothing else uses it.
18
+ { handle: "nodes", functions: ["read", "create", "write", "share"] },
6
19
  // ⚠️ No `approve`. The approval node is gone (#73), and this list is what Intel declares to Gate:
7
20
  // a function nobody asks about is a permission an operator has to decide on for no reason. An
8
21
  // installation that already granted it keeps a harmless leftover — bootstrap declares, it does
@@ -12,15 +25,9 @@ const interfaces = [
12
25
  functions: ["read", "create", "write", "publish", "run", "share"],
13
26
  },
14
27
  { handle: "tools", functions: ["read", "test", "execute", "admin"] },
15
- // Declared here, and not by a service of its own, because Gate scopes the rules it returns to the
16
- // service whose key asked (least privilege). The agent runtime authorizes its callers with this
17
- // installation's Gate service key against the same audience Intel uses, so a handle registered
18
- // anywhere else would never appear in the rules that `can("agents", "run")` reads.
19
- //
20
- // Without it there is no state between "administrator" and "not at all": the runtime falls back to
21
- // `intel:admin`, which is the first-grant exit in the same sense as everywhere else, not the way a
22
- // team lets a colleague talk to an agent.
23
- { handle: "agents", functions: ["run"] },
28
+ // ⚠️ `agents:run` is deliberately NOT here any more (#390). `bootstrap` declares, it never
29
+ // revokes, so an installation that has the interface keeps it as a harmless leftover — but a new
30
+ // one is not asked to decide about a permission nothing reads.
24
31
  // `mcp:connect` means the same thing at every MCP service of this installation. A separate name
25
32
  // for the same thing forces the operator to check, service by service, which permission carries
26
33
  // portal access.
@@ -124,7 +131,7 @@ export function createCli(deps) {
124
131
  if (!intelUrl || !token) {
125
132
  return fail("INTEL_URL and a short-lived INTEL_OPERATOR_TOKEN must be set.");
126
133
  }
127
- const response = await deps.fetch(`${intelUrl}/api/v1/search/reindex`, {
134
+ const response = await deps.fetch(`${intelUrl}/api/v1/nodes/reindex`, {
128
135
  method: "POST",
129
136
  headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
130
137
  body: "{}",
@@ -1,4 +1,4 @@
1
- import type { FlowGraph, FlowNode } from "@anchrd/intel-contract";
1
+ import type { FlowGraph, FlowNode } from "@anchrd/intel-contract/flow";
2
2
  import type { CompiledFlow, FlowDeps, FlowService } from "./flows.types.js";
3
3
  type SubflowNode = Extract<FlowNode, {
4
4
  kind: "subflow";
@@ -1,4 +1,4 @@
1
- import { flowNodeLayer } from "@anchrd/intel-contract";
1
+ import { flowNodeLayer } from "@anchrd/intel-contract/flow";
2
2
  import { IntelError } from "../shared/intel-error/intel-error.js";
3
3
  import { plainTitle } from "../shared/plain-title/plain-title.js";
4
4
  function invalid(detail) {
@@ -1,4 +1,7 @@
1
- import type { ArchiveFlowInput, CancelFlowRunInput, CompleteFlowRunStepInput, CreateFlowInput, Flow, FlowDocument, FlowGraph, FlowPublishPreview, FlowRequirements, FlowRun, FlowRunHistory, FlowRunList, FlowRunStep, FlowValidation, FlowVersion, FlowVersionList, FlowVersionSummary, GetFlowVersionInput, ListFlowRunsInput, ListFlowsInput, Node, PreviewFlowPublishInput, PublishFlowInput, RelationGraph, RelationGraphInput, ResourceVerb, SaveFlowVersionInput, StartFlowRunInput, UnpublishFlowInput, UpdateFlowInput } from "@anchrd/intel-contract";
1
+ import type { ArchiveFlowInput, CreateFlowInput, Flow, FlowDocument, FlowGraph, FlowPublishPreview, FlowRequirements, FlowValidation, FlowVersion, FlowVersionList, FlowVersionSummary, GetFlowVersionInput, ListFlowsInput, PreviewFlowPublishInput, PublishFlowInput, RelationGraph, RelationGraphInput, SaveFlowVersionInput, UnpublishFlowInput, UpdateFlowInput } from "@anchrd/intel-contract/flow";
2
+ import type { CancelFlowRunInput, CompleteFlowRunStepInput, FlowRun, FlowRunHistory, FlowRunList, FlowRunStep, ListFlowRunsInput, StartFlowRunInput } from "@anchrd/intel-contract/flow-run";
3
+ import type { Node } from "@anchrd/intel-contract/node";
4
+ import type { ResourceVerb } from "@anchrd/intel-contract/share";
2
5
  export type FlowPrincipal = Pick<FlowActor, "id" | "email" | "isAdmin">;
3
6
  export type FlowCallReach = "subtree" | "library" | "out-of-reach";
4
7
  export interface FlowRunChainEntry {