@tangle-network/agent-app 0.43.76 → 0.44.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/DesignCanvas-Z362I3R3.js +10 -0
- package/dist/{DesignCanvasEditor-FJIVYOA2.js → DesignCanvasEditor-ZFE2W4OJ.js} +4 -4
- package/dist/assets/index.d.ts +4 -4
- package/dist/assets/index.js +223 -11
- package/dist/assets/index.js.map +1 -1
- package/dist/assistant/index.d.ts +7 -7
- package/dist/assistant/index.js +3 -3
- package/dist/assistant/index.js.map +1 -1
- package/dist/{attachment-validation-Dv1A_Puy.d.ts → attachment-validation-DRuLEjAE.d.ts} +1 -1
- package/dist/{auth-_FU8w01b.d.ts → auth-anc7mv2W.d.ts} +2 -2
- package/dist/chat-routes/index.d.ts +14 -11
- package/dist/chat-routes/index.js +16 -17
- package/dist/chat-routes/index.js.map +1 -1
- package/dist/chat-store/index.d.ts +26 -7
- package/dist/chat-store/index.js +14 -5
- package/dist/chat-store/index.js.map +1 -1
- package/dist/{chunk-ROLFDOMJ.js → chunk-4TI7QWLW.js} +3 -3
- package/dist/{chunk-3JUTOVUH.js → chunk-6KMAM7BL.js} +1 -1
- package/dist/chunk-6KMAM7BL.js.map +1 -0
- package/dist/{chunk-WL7XHLDK.js → chunk-ICOHEZK6.js} +77 -5
- package/dist/chunk-ICOHEZK6.js.map +1 -0
- package/dist/{chunk-22GLESKE.js → chunk-O63WWYET.js} +2 -4
- package/dist/chunk-O63WWYET.js.map +1 -0
- package/dist/{chunk-E7N67FYI.js → chunk-Q3FONVAK.js} +5 -5
- package/dist/{chunk-E7N67FYI.js.map → chunk-Q3FONVAK.js.map} +1 -1
- package/dist/{chunk-RXOTWZ4G.js → chunk-TKRI463Z.js} +4 -4
- package/dist/chunk-TKRI463Z.js.map +1 -0
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.js +123 -4
- package/dist/config/index.js.map +1 -1
- package/dist/{contract-B3h7peV3.d.ts → contract-CEewO6DI.d.ts} +1 -1
- package/dist/design-canvas/index.d.ts +4 -4
- package/dist/design-canvas-react/index.js +7 -7
- package/dist/design-canvas-react/lazy.js +1 -1
- package/dist/eval/index.d.ts +1 -1
- package/dist/eval/index.js +22 -8
- package/dist/eval/index.js.map +1 -1
- package/dist/{flow-types-CqomVAUN.d.ts → flow-types-CJxEmaRy.d.ts} +1 -1
- package/dist/integrations/index.js +67 -5
- package/dist/integrations/index.js.map +1 -1
- package/dist/interactions/index.d.ts +6 -4
- package/dist/interactions/index.js +1 -2
- package/dist/knowledge/index.js +63 -4
- package/dist/knowledge/index.js.map +1 -1
- package/dist/knowledge-loop/index.d.ts +1 -1
- package/dist/knowledge-loop/index.js +94 -4
- package/dist/knowledge-loop/index.js.map +1 -1
- package/dist/{mcp-BjPqQ-3C.d.ts → mcp-D3qVzbE1.d.ts} +2 -2
- package/dist/{mcp-rpc-BfUOsalw.d.ts → mcp-rpc-CzU5LWWT.d.ts} +1 -1
- package/dist/missions/index.js +1143 -23
- package/dist/missions/index.js.map +1 -1
- package/dist/{model-DmdkIteM.d.ts → model-CdCDfBA9.d.ts} +1 -1
- package/dist/object-store/index.js +113 -8
- package/dist/object-store/index.js.map +1 -1
- package/dist/{parts-2ymE5cs-.d.ts → parts-Co_lFgLI.d.ts} +3 -3
- package/dist/platform/index.d.ts +1 -1
- package/dist/preflight/cli.d.ts +13 -0
- package/dist/preflight/cli.js +50 -0
- package/dist/preflight/cli.js.map +1 -0
- package/dist/preset-cloudflare/index.d.ts +1 -1
- package/dist/preset-cloudflare/index.js +284 -11
- package/dist/preset-cloudflare/index.js.map +1 -1
- package/dist/{queue-C24V13h9.d.ts → queue-CD5-_VTX.d.ts} +1 -1
- package/dist/redact/index.js +116 -8
- package/dist/redact/index.js.map +1 -1
- package/dist/runtime/index.d.ts +19 -111
- package/dist/runtime/index.js +234 -14
- package/dist/runtime/index.js.map +1 -1
- package/dist/sandbox/index.d.ts +3 -3
- package/dist/sandbox/index.js +2 -3
- package/dist/sequences/index.d.ts +4 -4
- package/dist/stream/index.d.ts +4 -4
- package/dist/{stream-normalizer-QYUl4vnl.d.ts → stream-normalizer-DnuqkZvw.d.ts} +2 -2
- package/dist/tangle/index.js +42 -4
- package/dist/tangle/index.js.map +1 -1
- package/dist/teams/index.js +5 -5
- package/dist/teams/invitations-api.js +4 -4
- package/dist/teams-react/index.js +3 -3
- package/dist/theme/index.js +0 -1
- package/dist/tools/index.d.ts +6 -6
- package/dist/tools/index.js +5 -7
- package/dist/trace/index.d.ts +1 -1
- package/dist/trace/index.js +179 -10
- package/dist/trace/index.js.map +1 -1
- package/dist/{turn-buffer-BaSgxVmK.d.ts → turn-buffer-BcPfhr1_.d.ts} +1 -1
- package/dist/turn-stream/index.d.ts +1 -1
- package/dist/{types-CBRyqijY.d.ts → types-BCxK0wyS.d.ts} +1 -1
- package/dist/{types-CEchbvgz.d.ts → types-XIZqIdX1.d.ts} +1 -1
- package/dist/web-react/index.d.ts +10 -10
- package/dist/web-react/index.js +5 -5
- package/dist/work-product/index.d.ts +4 -4
- package/dist/work-product/index.js +735 -15
- package/dist/work-product/index.js.map +1 -1
- package/dist/work-product-react/index.d.ts +1 -1
- package/dist/work-product-react/index.js.map +1 -1
- package/package.json +4 -19
- package/dist/DesignCanvas-UNL34LS2.js +0 -12
- package/dist/chunk-22GLESKE.js.map +0 -1
- package/dist/chunk-3JUTOVUH.js.map +0 -1
- package/dist/chunk-5EQCITY3.js +0 -20
- package/dist/chunk-5EQCITY3.js.map +0 -1
- package/dist/chunk-5SD6HT2V.js +0 -236
- package/dist/chunk-5SD6HT2V.js.map +0 -1
- package/dist/chunk-5TESA4SN.js +0 -74
- package/dist/chunk-5TESA4SN.js.map +0 -1
- package/dist/chunk-6GQ5DKFK.js +0 -920
- package/dist/chunk-6GQ5DKFK.js.map +0 -1
- package/dist/chunk-7ESQUSAC.js +0 -343
- package/dist/chunk-7ESQUSAC.js.map +0 -1
- package/dist/chunk-7LNGJDNA.js +0 -1
- package/dist/chunk-7LNGJDNA.js.map +0 -1
- package/dist/chunk-AP2UXKUK.js +0 -69
- package/dist/chunk-AP2UXKUK.js.map +0 -1
- package/dist/chunk-FA4XR66Y.js +0 -32
- package/dist/chunk-FA4XR66Y.js.map +0 -1
- package/dist/chunk-FKCB5FTD.js +0 -126
- package/dist/chunk-FKCB5FTD.js.map +0 -1
- package/dist/chunk-GPBRL2XR.js +0 -102
- package/dist/chunk-GPBRL2XR.js.map +0 -1
- package/dist/chunk-HRH7ASAG.js +0 -759
- package/dist/chunk-HRH7ASAG.js.map +0 -1
- package/dist/chunk-HYTIHYNV.js +0 -297
- package/dist/chunk-HYTIHYNV.js.map +0 -1
- package/dist/chunk-LGBO24FL.js +0 -190
- package/dist/chunk-LGBO24FL.js.map +0 -1
- package/dist/chunk-NLSSFLLS.js +0 -1168
- package/dist/chunk-NLSSFLLS.js.map +0 -1
- package/dist/chunk-OSMNYPOG.js +0 -129
- package/dist/chunk-OSMNYPOG.js.map +0 -1
- package/dist/chunk-QYOD3K56.js +0 -124
- package/dist/chunk-QYOD3K56.js.map +0 -1
- package/dist/chunk-RXOTWZ4G.js.map +0 -1
- package/dist/chunk-UAKFCMWK.js +0 -1
- package/dist/chunk-UAKFCMWK.js.map +0 -1
- package/dist/chunk-UKTYKG57.js +0 -48
- package/dist/chunk-UKTYKG57.js.map +0 -1
- package/dist/chunk-UOAYS72M.js +0 -80
- package/dist/chunk-UOAYS72M.js.map +0 -1
- package/dist/chunk-WL7XHLDK.js.map +0 -1
- package/dist/composer/index.d.ts +0 -2
- package/dist/composer/index.js +0 -22
- package/dist/composer/index.js.map +0 -1
- package/dist/core-7qIM7svy.d.ts +0 -21
- package/dist/durable-chat/index.d.ts +0 -464
- package/dist/durable-chat/index.js +0 -59
- package/dist/durable-chat/index.js.map +0 -1
- package/dist/index.d.ts +0 -51
- package/dist/index.js +0 -827
- package/dist/index.js.map +0 -1
- /package/dist/{DesignCanvas-UNL34LS2.js.map → DesignCanvas-Z362I3R3.js.map} +0 -0
- /package/dist/{DesignCanvasEditor-FJIVYOA2.js.map → DesignCanvasEditor-ZFE2W4OJ.js.map} +0 -0
- /package/dist/{chunk-ROLFDOMJ.js.map → chunk-4TI7QWLW.js.map} +0 -0
package/dist/config/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { KnowledgeRequirementSpec } from '../knowledge/index.js';
|
|
2
2
|
export { SatisfiedByRule } from '../knowledge/index.js';
|
|
3
|
-
import {
|
|
3
|
+
import { T as TangleModelConfig } from '../model-CdCDfBA9.js';
|
|
4
4
|
import '@tangle-network/agent-eval';
|
|
5
5
|
|
|
6
6
|
/**
|
package/dist/config/index.js
CHANGED
|
@@ -1,7 +1,126 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
}
|
|
1
|
+
// src/config/index.ts
|
|
2
|
+
function defineAgentApp(config) {
|
|
3
|
+
return config;
|
|
4
|
+
}
|
|
5
|
+
var agentAppConfigJsonSchema = {
|
|
6
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
7
|
+
$id: "https://tangle.tools/schemas/agent-app-config.json",
|
|
8
|
+
title: "AgentAppConfig",
|
|
9
|
+
description: "The declarative domain surface of a Tangle agent product.",
|
|
10
|
+
type: "object",
|
|
11
|
+
additionalProperties: false,
|
|
12
|
+
required: ["identity", "taxonomy", "knowledge", "integrations"],
|
|
13
|
+
properties: {
|
|
14
|
+
identity: {
|
|
15
|
+
type: "object",
|
|
16
|
+
additionalProperties: false,
|
|
17
|
+
required: ["name", "persona"],
|
|
18
|
+
properties: {
|
|
19
|
+
name: { type: "string", description: "Product/agent name." },
|
|
20
|
+
persona: { type: "string", description: "One-paragraph persona \u2014 the system-prompt spine." },
|
|
21
|
+
systemPromptFragments: {
|
|
22
|
+
type: "array",
|
|
23
|
+
items: { type: "string" },
|
|
24
|
+
description: "Verbatim system-prompt fragments appended after the persona, in order."
|
|
25
|
+
},
|
|
26
|
+
disclaimers: {
|
|
27
|
+
type: "object",
|
|
28
|
+
additionalProperties: { type: "string" },
|
|
29
|
+
description: "Named disclaimers keyed by stable id; values are literal text."
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
taxonomy: {
|
|
34
|
+
type: "object",
|
|
35
|
+
additionalProperties: false,
|
|
36
|
+
required: ["proposalTypes", "regulatedTypes"],
|
|
37
|
+
properties: {
|
|
38
|
+
proposalTypes: {
|
|
39
|
+
type: "array",
|
|
40
|
+
items: { type: "string" },
|
|
41
|
+
description: "Closed allow-list of proposal types the product can emit."
|
|
42
|
+
},
|
|
43
|
+
regulatedTypes: {
|
|
44
|
+
type: "array",
|
|
45
|
+
items: { type: "string" },
|
|
46
|
+
description: "Subset of proposalTypes that is approval-gated (certified-human required)."
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
knowledge: {
|
|
51
|
+
type: "object",
|
|
52
|
+
additionalProperties: false,
|
|
53
|
+
required: ["sources", "requirements"],
|
|
54
|
+
properties: {
|
|
55
|
+
sources: {
|
|
56
|
+
type: "array",
|
|
57
|
+
description: "Sources the acquisition loop may draw on.",
|
|
58
|
+
items: {
|
|
59
|
+
type: "object",
|
|
60
|
+
additionalProperties: false,
|
|
61
|
+
required: ["uri"],
|
|
62
|
+
properties: {
|
|
63
|
+
uri: { type: "string", description: "Where the source lives (opaque to agent-app)." },
|
|
64
|
+
kind: { type: "string", description: "Optional source classifier (web/vault/regulation/\u2026)." }
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
requirements: {
|
|
69
|
+
type: "array",
|
|
70
|
+
description: "Declarative KnowledgeRequirementSpec[] (../knowledge) that gate the loop.",
|
|
71
|
+
items: { type: "object", additionalProperties: true }
|
|
72
|
+
},
|
|
73
|
+
loop: {
|
|
74
|
+
type: "object",
|
|
75
|
+
additionalProperties: false,
|
|
76
|
+
description: "Acquisition-loop config.",
|
|
77
|
+
properties: {
|
|
78
|
+
goal: { type: "string", description: "Acquisition goal in natural language." },
|
|
79
|
+
minConfidence: {
|
|
80
|
+
type: "number",
|
|
81
|
+
minimum: 0,
|
|
82
|
+
maximum: 1,
|
|
83
|
+
description: "Minimum aggregate confidence the loop must reach."
|
|
84
|
+
},
|
|
85
|
+
freshness: { type: "string", description: "How fresh acquired knowledge must be." }
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
integrations: {
|
|
91
|
+
type: "object",
|
|
92
|
+
additionalProperties: false,
|
|
93
|
+
required: ["enabled"],
|
|
94
|
+
properties: {
|
|
95
|
+
enabled: {
|
|
96
|
+
type: "array",
|
|
97
|
+
items: { type: "string" },
|
|
98
|
+
description: "Enabled agent-integrations catalog kinds."
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
ui: {
|
|
103
|
+
type: "object",
|
|
104
|
+
additionalProperties: false,
|
|
105
|
+
description: "UI capability flags.",
|
|
106
|
+
properties: {
|
|
107
|
+
generatedUi: { type: "boolean", description: "Whether the agent may emit generated UI." }
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
model: {
|
|
111
|
+
type: "object",
|
|
112
|
+
additionalProperties: false,
|
|
113
|
+
description: "Resolved TangleModelConfig (../runtime). Omit to resolve from env.",
|
|
114
|
+
required: ["provider", "model", "apiKey", "baseUrl"],
|
|
115
|
+
properties: {
|
|
116
|
+
provider: { type: "string", enum: ["openai-compat", "anthropic"] },
|
|
117
|
+
model: { type: "string" },
|
|
118
|
+
apiKey: { type: "string" },
|
|
119
|
+
baseUrl: { type: "string" }
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
};
|
|
5
124
|
export {
|
|
6
125
|
agentAppConfigJsonSchema,
|
|
7
126
|
defineAgentApp
|
package/dist/config/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/config/index.ts"],"sourcesContent":["/**\n * `@tangle-network/agent-app/config` — the typed `AgentAppConfig` contract.\n *\n * This is the single declarative DATA surface a coding agent fills to stand up a\n * new agent product. Everything an agent product otherwise hand-rolls as\n * imperative wiring — who the agent is, which proposal types exist and which are\n * approval-gated, what knowledge the control loop requires, which integrations\n * are connectable, how the model resolves — is expressed here as plain data the\n * rest of agent-app's modules consume through their typed seams:\n *\n * - `identity` → the system-prompt + disclaimer surface the chat pipeline reads.\n * - `taxonomy` → which `submit_proposal` types the `./tools` side channel\n * accepts, and which the approval queue treats as regulated\n * (certified-human-gated).\n * - `knowledge` → the `./knowledge` requirement specs that gate the loop, plus\n * the acquisition-loop goal/threshold the researcher pursues.\n * - `integrations` → which `@tangle-network/agent-integrations` catalog kinds the\n * product enables.\n * - `ui` → whether the agent may emit generated UI (`render_ui`).\n * - `model` → the `./runtime` `TangleModelConfig` (or null to resolve from env).\n *\n * Layering: this module is the CONTRACT only — pure types + an identity helper.\n * It introduces no behavior and no engine dependency; it REUSES the existing\n * `KnowledgeRequirementSpec`/`SatisfiedByRule` (from `../knowledge`) and\n * `TangleModelConfig` (from `../runtime`) rather than redefining them, so the\n * config a product authors is the exact shape those modules already consume.\n * Steps that build the composer/loader read this file as the schema floor.\n */\n\nimport type {\n KnowledgeRequirementSpec,\n SatisfiedByRule,\n} from '../knowledge/index'\nimport type { TangleModelConfig } from '../runtime/index'\n\n// Re-export the borrowed types so a config author has a single import surface\n// (`@tangle-network/agent-app/config`) and never has to reach into `../knowledge`\n// or `../runtime` to spell out a field's type. These are the SAME types the\n// knowledge gate and runtime model resolver consume — not parallel copies.\nexport type { KnowledgeRequirementSpec, SatisfiedByRule, TangleModelConfig }\n\n/**\n * Who the agent is, as data. Composed into the chat pipeline's system prompt;\n * never baked into agent-app (a domain value, per the layering contract).\n */\nexport interface AgentIdentityConfig {\n /** Product/agent name, e.g. `\"Acme Support Copilot\"`. Shown to the user and\n * available to the system-prompt builder. */\n name: string\n /** One-paragraph persona statement — the agent's role, voice, and remit. The\n * spine of the system prompt. */\n persona: string\n /** Additional system-prompt fragments appended verbatim after the persona\n * (standing workflows, hard rules, tone). Order is preserved. Optional. */\n systemPromptFragments?: string[]\n /** Named disclaimers the product surfaces (e.g. a regulatory human-in-the-loop\n * notice). Keyed by a stable id (`compliance`, `not-advice`, …) so the chat\n * pipeline / UI can select one by name. Values are the literal text. Optional. */\n disclaimers?: Record<string, string>\n}\n\n/**\n * The proposal taxonomy, as data. `proposalTypes` is the closed set of\n * `submit_proposal` types the `./tools` side channel accepts; `regulatedTypes`\n * is the subset that is approval-gated — the executor refuses to run one without\n * a certified human approver. `regulatedTypes` MUST be a subset of\n * `proposalTypes` (validated by the loader step; not enforced at the type level).\n */\nexport interface AgentTaxonomyConfig {\n /** Every proposal type this product can emit, e.g.\n * `['recommend', 'contact', 'escalate']`. The closed allow-list\n * the tool layer validates a `submit_proposal` call against. */\n proposalTypes: string[]\n /** The subset of `proposalTypes` that is regulated → cannot execute without a\n * certified-human approver. The approval executor reads this to decide which\n * proposals are fail-loud certified-gated. */\n regulatedTypes: string[]\n}\n\n/** A knowledge source the acquisition loop / researcher may draw on. */\nexport interface KnowledgeSourceSpec {\n /** Where the source lives — a URL, a `vault://` path, an integration ref, etc.\n * Opaque to agent-app; the consumer's loader resolves it. */\n uri: string\n /** Optional source classifier the researcher uses to pick a fetch strategy,\n * e.g. `'web'`, `'vault'`, `'regulation'`, `'integration'`. Free-form. */\n kind?: string\n}\n\n/**\n * The knowledge-acquisition loop config — the goal the researcher pursues and\n * the gate it must clear before the loop is considered satisfied. All optional;\n * a product with only static requirement specs omits it.\n */\nexport interface KnowledgeLoopConfig {\n /** The acquisition goal in natural language, e.g.\n * `\"ground every quoted premium against a real policy record\"`. */\n goal?: string\n /** The minimum aggregate confidence [0, 1] the loop must reach to pass its\n * gate. The runtime control loop blocks below this. Default decided by the\n * consumer's loop wiring when omitted. */\n minConfidence?: number\n /** How fresh acquired knowledge must be, e.g. `'static'`, `'7d'`, `'session'`.\n * Free-form; the consumer's loop interprets it. */\n freshness?: string\n}\n\n/**\n * The knowledge surface, as data. `sources` are what the researcher may read;\n * `requirements` are the declarative `./knowledge` specs that gate the control\n * loop (reused verbatim — the same `KnowledgeRequirementSpec` the gate scores);\n * `loop` configures the acquisition pass.\n */\nexport interface AgentKnowledgeConfig {\n /** Sources the acquisition loop / researcher may draw on. */\n sources: KnowledgeSourceSpec[]\n /** The declarative requirement specs that gate the loop. Reuses\n * `KnowledgeRequirementSpec` from `../knowledge` — `buildKnowledgeRequirements`\n * + `deriveSignals` consume these directly. */\n requirements: KnowledgeRequirementSpec[]\n /** Optional acquisition-loop config (goal + confidence gate + freshness). */\n loop?: KnowledgeLoopConfig\n}\n\n/**\n * Which integrations the product enables, as data. `enabled` lists\n * `@tangle-network/agent-integrations` catalog kinds the product connects\n * (e.g. `['salesforce', 'gmail', 'whatsapp']`); the integration hub resolves\n * each to a connector. Strings, not connector objects — agent-app bakes no\n * catalog value.\n */\nexport interface AgentIntegrationsConfig {\n /** Catalog kinds this product enables. */\n enabled: string[]\n}\n\n/** UI capability flags, as data. */\nexport interface AgentUiConfig {\n /** Whether the agent may emit generated UI (the `render_ui` / OpenUI side\n * channel). When false/omitted, the tool layer can omit/refuse the tool.\n * Default behavior decided by the consumer; omit to leave unset. */\n generatedUi?: boolean\n}\n\n/**\n * The declarative domain surface of a Tangle agent product.\n *\n * A coding agent fills THIS object and nothing else to define a product's\n * identity, proposal taxonomy, knowledge gate, integrations, UI capability, and\n * model. Every field is DATA consumed by an agent-app module through its typed\n * seam — no field is behavior. Author it through {@link defineAgentApp} for\n * autocomplete and a single import.\n */\nexport interface AgentAppConfig {\n /** Who the agent is — name, persona, system-prompt fragments, disclaimers. */\n identity: AgentIdentityConfig\n /** Proposal types + which are regulated/approval-gated. */\n taxonomy: AgentTaxonomyConfig\n /** Knowledge sources, requirement specs (the loop gate), and loop config. */\n knowledge: AgentKnowledgeConfig\n /** Enabled integration catalog kinds. */\n integrations: AgentIntegrationsConfig\n /** UI capability flags. Optional. */\n ui?: AgentUiConfig\n /** The resolved model config (`../runtime`'s `TangleModelConfig`). Omit to\n * resolve from env at boot via `resolveTangleModelConfig`. */\n model?: TangleModelConfig\n}\n\n/**\n * Identity helper: returns its argument unchanged, but anchors inference so a\n * coding agent authoring a config gets full autocomplete + type-checking from a\n * single import. The canonical way to declare a product config:\n *\n * ```ts\n * import { defineAgentApp } from '@tangle-network/agent-app/config'\n *\n * export const config = defineAgentApp({\n * identity: { name: 'Acme Ops', persona: '…' },\n * taxonomy: { proposalTypes: ['recommend', 'contact'], regulatedTypes: ['recommend'] },\n * knowledge: { sources: [], requirements: [] },\n * integrations: { enabled: ['salesforce'] },\n * })\n * ```\n */\nexport function defineAgentApp<const T extends AgentAppConfig>(config: T): T {\n return config\n}\n\n/**\n * Machine-readable JSON Schema (draft 2020-12) for {@link AgentAppConfig}.\n *\n * The schema FLOOR a non-TypeScript coding agent (or a config validator/UI) reads\n * to know the shape without parsing the `.d.ts`. Kept in lockstep with the\n * interfaces above by the config test, which asserts the documented fields are\n * present. `KnowledgeRequirementSpec`'s full sub-shape is intentionally left\n * `additionalProperties: true` here — its authoritative definition lives in\n * `../knowledge`; this floor pins only the fields the config contract owns.\n */\nexport const agentAppConfigJsonSchema = {\n $schema: 'https://json-schema.org/draft/2020-12/schema',\n $id: 'https://tangle.tools/schemas/agent-app-config.json',\n title: 'AgentAppConfig',\n description: 'The declarative domain surface of a Tangle agent product.',\n type: 'object',\n additionalProperties: false,\n required: ['identity', 'taxonomy', 'knowledge', 'integrations'],\n properties: {\n identity: {\n type: 'object',\n additionalProperties: false,\n required: ['name', 'persona'],\n properties: {\n name: { type: 'string', description: 'Product/agent name.' },\n persona: { type: 'string', description: 'One-paragraph persona — the system-prompt spine.' },\n systemPromptFragments: {\n type: 'array',\n items: { type: 'string' },\n description: 'Verbatim system-prompt fragments appended after the persona, in order.',\n },\n disclaimers: {\n type: 'object',\n additionalProperties: { type: 'string' },\n description: 'Named disclaimers keyed by stable id; values are literal text.',\n },\n },\n },\n taxonomy: {\n type: 'object',\n additionalProperties: false,\n required: ['proposalTypes', 'regulatedTypes'],\n properties: {\n proposalTypes: {\n type: 'array',\n items: { type: 'string' },\n description: 'Closed allow-list of proposal types the product can emit.',\n },\n regulatedTypes: {\n type: 'array',\n items: { type: 'string' },\n description: 'Subset of proposalTypes that is approval-gated (certified-human required).',\n },\n },\n },\n knowledge: {\n type: 'object',\n additionalProperties: false,\n required: ['sources', 'requirements'],\n properties: {\n sources: {\n type: 'array',\n description: 'Sources the acquisition loop may draw on.',\n items: {\n type: 'object',\n additionalProperties: false,\n required: ['uri'],\n properties: {\n uri: { type: 'string', description: 'Where the source lives (opaque to agent-app).' },\n kind: { type: 'string', description: 'Optional source classifier (web/vault/regulation/…).' },\n },\n },\n },\n requirements: {\n type: 'array',\n description: \"Declarative KnowledgeRequirementSpec[] (../knowledge) that gate the loop.\",\n items: { type: 'object', additionalProperties: true },\n },\n loop: {\n type: 'object',\n additionalProperties: false,\n description: 'Acquisition-loop config.',\n properties: {\n goal: { type: 'string', description: 'Acquisition goal in natural language.' },\n minConfidence: {\n type: 'number',\n minimum: 0,\n maximum: 1,\n description: 'Minimum aggregate confidence the loop must reach.',\n },\n freshness: { type: 'string', description: 'How fresh acquired knowledge must be.' },\n },\n },\n },\n },\n integrations: {\n type: 'object',\n additionalProperties: false,\n required: ['enabled'],\n properties: {\n enabled: {\n type: 'array',\n items: { type: 'string' },\n description: 'Enabled agent-integrations catalog kinds.',\n },\n },\n },\n ui: {\n type: 'object',\n additionalProperties: false,\n description: 'UI capability flags.',\n properties: {\n generatedUi: { type: 'boolean', description: 'Whether the agent may emit generated UI.' },\n },\n },\n model: {\n type: 'object',\n additionalProperties: false,\n description: \"Resolved TangleModelConfig (../runtime). Omit to resolve from env.\",\n required: ['provider', 'model', 'apiKey', 'baseUrl'],\n properties: {\n provider: { type: 'string', enum: ['openai-compat', 'anthropic'] },\n model: { type: 'string' },\n apiKey: { type: 'string' },\n baseUrl: { type: 'string' },\n },\n },\n },\n} as const\n"],"mappings":"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","names":[]}
|
|
@@ -182,4 +182,4 @@ declare function stampInteractionAnswers(parts: Array<Record<string, unknown>>,
|
|
|
182
182
|
* Returns null (caller logs) when the part is not one of ours. */
|
|
183
183
|
declare function persistedPartToInteraction(part: Record<string, unknown>): ChatInteraction | null;
|
|
184
184
|
|
|
185
|
-
export { noticePart as A, noticePartKey as B, type
|
|
185
|
+
export { noticePart as A, noticePartKey as B, type ChatInteractionStatus as C, parseInteractionAnswers as D, parseInteractionCancel as E, parseInteractionRequest as F, persistedPartToInteraction as G, questionInteractionContentSignature as H, type InteractionAnswers as I, stampInteractionAnswers as J, type NoticeKind as N, type ParseInteractionAnswersResult as P, type ChatInteractionField as a, type ChatInteraction as b, type InteractionCancelData as c, type ChatSelectField as d, type InteractionRequestWire as e, type ChatFreeTextField as f, type ComposerAnswerDelivery as g, INTERACTION_CANCEL_EVENT as h, INTERACTION_EVENT as i, INTERACTION_RESOLVED_EVENT as j, type InteractionAnswerValue as k, type InteractionPersistedPart as l, type NoticePersistedPart as m, type ParseInteractionResult as n, canTransitionInteractionStatus as o, cancelStatusFor as p, composerAnswerData as q, composerAnswerDeliveries as r, dedupeQuestionInteractionsByContent as s, fieldAcceptsFreeText as t, interactionFromWireRequest as u, interactionPartKey as v, interactionToPersistedPart as w, isRenderableInteractionKind as x, isSafeInteractionFieldKey as y, isTerminalInteractionStatus as z };
|
|
@@ -5,10 +5,10 @@ export { A as AddElementOperation, b as AddPageOperation, c as ApplyDataOperatio
|
|
|
5
5
|
import { a as SceneStore, N as NewSceneDecision, b as SceneDocumentRecord } from '../store-CqfDtnPQ.js';
|
|
6
6
|
export { c as SceneDecision, d as SceneExportFormat, e as SceneExportRecord, S as SceneStoreScope } from '../store-CqfDtnPQ.js';
|
|
7
7
|
export { C as CHANNEL_PRESETS, a as ChannelPreset, b as ChannelPresetId, c as ChannelScaleResult, E as EXPORT_PRESETS, d as ExportCropRect, e as ExportFormat, f as ExportPreset, S as SIZE_PRESETS, g as SizePreset, h as bleedAwareExportBounds, i as bleedAwareExportRect, j as findPreset, m as matchPreset, r as requireChannelPreset, s as scaleForPreset, k as scalePageForChannelPreset } from '../export-presets-mgVulRaV.js';
|
|
8
|
-
import {
|
|
9
|
-
import { S as ScopedMcpServerEntryOptions, A as AppToolMcpServer } from '../mcp-
|
|
10
|
-
import '../types-
|
|
11
|
-
import '../auth-
|
|
8
|
+
import { a as McpToolDefinition } from '../mcp-rpc-CzU5LWWT.js';
|
|
9
|
+
import { S as ScopedMcpServerEntryOptions, A as AppToolMcpServer } from '../mcp-D3qVzbE1.js';
|
|
10
|
+
import '../types-BCxK0wyS.js';
|
|
11
|
+
import '../auth-anc7mv2W.js';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Pre-write validation for scene operations. Every rule runs against a
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
downloadDataUrl,
|
|
13
13
|
exportDocumentJson,
|
|
14
14
|
exportPageDataUrl
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-Q3FONVAK.js";
|
|
16
16
|
import {
|
|
17
17
|
BTN,
|
|
18
18
|
BTN_ACTIVE,
|
|
@@ -41,7 +41,8 @@ import {
|
|
|
41
41
|
buildRulerTicks,
|
|
42
42
|
formatRulerLabel,
|
|
43
43
|
selectTickStep
|
|
44
|
-
} from "../chunk-
|
|
44
|
+
} from "../chunk-O63WWYET.js";
|
|
45
|
+
import "../chunk-TZO3SOUL.js";
|
|
45
46
|
import "../chunk-ZN5J47UX.js";
|
|
46
47
|
import {
|
|
47
48
|
DEFAULT_INSERT_TEMPLATES,
|
|
@@ -82,16 +83,15 @@ import {
|
|
|
82
83
|
setPagePropsCommand,
|
|
83
84
|
ungroupElementCommand
|
|
84
85
|
} from "../chunk-VTWKH4YU.js";
|
|
86
|
+
import {
|
|
87
|
+
DesignCanvasChromeLazy,
|
|
88
|
+
DesignCanvasLazy
|
|
89
|
+
} from "../chunk-4TI7QWLW.js";
|
|
85
90
|
import {
|
|
86
91
|
assertSceneMediaSrc,
|
|
87
92
|
bleedAwareExportBounds,
|
|
88
93
|
scaleForPreset
|
|
89
94
|
} from "../chunk-VWOPOLVO.js";
|
|
90
|
-
import {
|
|
91
|
-
DesignCanvasChromeLazy,
|
|
92
|
-
DesignCanvasLazy
|
|
93
|
-
} from "../chunk-ROLFDOMJ.js";
|
|
94
|
-
import "../chunk-TZO3SOUL.js";
|
|
95
95
|
import "../chunk-PTUMBMVH.js";
|
|
96
96
|
|
|
97
97
|
// src/design-canvas-react/components/CanvasInsertPanel.tsx
|
package/dist/eval/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CompletionRequirement, RuntimeEventLike } from '@tangle-network/agent-eval';
|
|
2
2
|
export { CompletionRequirement, CompletionVerdict, CorrectnessChecker, ProducedState, RuntimeEventLike, SatisfiedBy, TaskGold, createLlmCorrectnessChecker, extractProducedState, verifyCompletion, weightedComposite } from '@tangle-network/agent-eval';
|
|
3
|
-
import {
|
|
3
|
+
import { A as AppToolProducedEvent } from '../types-BCxK0wyS.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Eval — the app-shell BRIDGE to `@tangle-network/agent-eval`, not a reimpl.
|
package/dist/eval/index.js
CHANGED
|
@@ -1,11 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
// src/eval/index.ts
|
|
2
|
+
import { verifyCompletion, extractProducedState, weightedComposite, createLlmCorrectnessChecker } from "@tangle-network/agent-eval";
|
|
3
|
+
function producedFromToolEvents(events) {
|
|
4
|
+
return events.map(
|
|
5
|
+
(e) => e.type === "proposal_created" ? { type: "proposal_created", proposalId: e.proposalId, title: e.title, status: e.status, content: e.content } : { type: "artifact", artifactId: `vault:${e.path}`, name: e.path, uri: `vault://${e.path}`, mimeType: "text/markdown", content: e.content }
|
|
6
|
+
);
|
|
7
|
+
}
|
|
8
|
+
var STOPWORDS = /* @__PURE__ */ new Set(["the", "a", "an", "and", "or", "for", "to", "of", "in", "on", "with", "review", "update", "new", "proposed"]);
|
|
9
|
+
function createTokenRecallChecker(opts = {}) {
|
|
10
|
+
const minRecall = opts.minRecall ?? 0.5;
|
|
11
|
+
const minLen = opts.minContentLength ?? 120;
|
|
12
|
+
return async (requirement, content) => {
|
|
13
|
+
const body = content.trim();
|
|
14
|
+
if (body.length < minLen) return { correct: false, reason: `content too thin (${body.length} chars) to be the deliverable` };
|
|
15
|
+
const tokens = requirement.title.toLowerCase().split(/[^a-z0-9]+/).filter((t) => t.length > 2 && !STOPWORDS.has(t));
|
|
16
|
+
if (tokens.length === 0) return { correct: true, reason: "requirement title has no significant tokens \u2014 structural match accepted" };
|
|
17
|
+
const lower = body.toLowerCase();
|
|
18
|
+
const hits = tokens.filter((t) => lower.includes(t)).length;
|
|
19
|
+
const recall = hits / tokens.length;
|
|
20
|
+
return recall >= minRecall ? { correct: true, reason: `content recalls ${hits}/${tokens.length} requirement tokens` } : { correct: false, reason: `content recalls only ${hits}/${tokens.length} requirement tokens` };
|
|
21
|
+
};
|
|
22
|
+
}
|
|
9
23
|
export {
|
|
10
24
|
createLlmCorrectnessChecker,
|
|
11
25
|
createTokenRecallChecker,
|
package/dist/eval/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/eval/index.ts"],"sourcesContent":["/**\n * Eval — the app-shell BRIDGE to `@tangle-network/agent-eval`, not a reimpl.\n *\n * The completion/scoring ENGINE lives in agent-eval (a peer dependency):\n * `verifyCompletion`, `extractProducedState`, `weightedComposite`,\n * `createLlmCorrectnessChecker`, and the `CompletionRequirement` / `TaskGold` /\n * `ProducedState` types — all re-exported here so a consumer has one import\n * root. This module adds only what agent-eval doesn't have and what is\n * app-shell-specific:\n *\n * 1. {@link producedFromToolEvents} — the bridge: turn the structured app-tool\n * side channel's `AppToolProducedEvent`s (from a tool runtime executor's\n * `onProduced`) into the `RuntimeEventLike`s agent-eval's\n * `extractProducedState` consumes. This is the one piece that knows about\n * the app-tool channel, so it belongs here, not in the engine.\n * 2. {@link createTokenRecallChecker} — a deterministic, no-LLM\n * `CorrectnessChecker` (agent-eval ships only the LLM one). For apps/tests\n * that gate completion without a judge call.\n *\n * Full campaigns (persona simulation, traces, scorecards, held-out gates) are\n * agent-eval's `runEvalCampaign` / `AgentDriver` / `BenchmarkRunner` — use them\n * directly; this module composes with them.\n */\nimport type { RuntimeEventLike, CompletionRequirement } from '@tangle-network/agent-eval'\nimport type { AppToolProducedEvent } from '../tools/types'\n\n// Re-export the engine so consumers import completion + scoring from one place.\nexport { verifyCompletion, extractProducedState, weightedComposite, createLlmCorrectnessChecker } from '@tangle-network/agent-eval'\nexport type {\n CompletionRequirement,\n TaskGold,\n ProducedState,\n SatisfiedBy,\n CompletionVerdict,\n CorrectnessChecker,\n RuntimeEventLike,\n} from '@tangle-network/agent-eval'\n\n/**\n * Bridge the app-tool side channel's produced events into the runtime-event\n * shape agent-eval's `extractProducedState` reads. Pipe it:\n * `verifyCompletion(taskGold, extractProducedState(producedFromToolEvents(events)), checker)`\n */\nexport function producedFromToolEvents(events: readonly AppToolProducedEvent[]): RuntimeEventLike[] {\n return events.map((e) =>\n e.type === 'proposal_created'\n ? { type: 'proposal_created', proposalId: e.proposalId, title: e.title, status: e.status, content: e.content }\n : { type: 'artifact', artifactId: `vault:${e.path}`, name: e.path, uri: `vault://${e.path}`, mimeType: 'text/markdown', content: e.content },\n )\n}\n\nconst STOPWORDS = new Set(['the', 'a', 'an', 'and', 'or', 'for', 'to', 'of', 'in', 'on', 'with', 'review', 'update', 'new', 'proposed'])\n\n/**\n * A deterministic `CorrectnessChecker` (agent-eval exports only\n * `createLlmCorrectnessChecker`). A produced item fulfils a requirement when\n * its content is substantive and recalls ≥ `minRecall` of the requirement\n * title's significant tokens. No network — the default gate for apps/tests\n * without an LLM judge. Pass to `verifyCompletion` as the checker.\n */\nexport function createTokenRecallChecker(opts: { minRecall?: number; minContentLength?: number } = {}): (\n requirement: CompletionRequirement,\n content: string,\n) => Promise<{ correct: boolean; reason: string }> {\n const minRecall = opts.minRecall ?? 0.5\n const minLen = opts.minContentLength ?? 120\n return async (requirement, content) => {\n const body = content.trim()\n if (body.length < minLen) return { correct: false, reason: `content too thin (${body.length} chars) to be the deliverable` }\n const tokens = requirement.title.toLowerCase().split(/[^a-z0-9]+/).filter((t) => t.length > 2 && !STOPWORDS.has(t))\n if (tokens.length === 0) return { correct: true, reason: 'requirement title has no significant tokens — structural match accepted' }\n const lower = body.toLowerCase()\n const hits = tokens.filter((t) => lower.includes(t)).length\n const recall = hits / tokens.length\n return recall >= minRecall\n ? { correct: true, reason: `content recalls ${hits}/${tokens.length} requirement tokens` }\n : { correct: false, reason: `content recalls only ${hits}/${tokens.length} requirement tokens` }\n }\n}\n"],"mappings":";AA2BA,SAAS,kBAAkB,sBAAsB,mBAAmB,mCAAmC;AAgBhG,SAAS,uBAAuB,QAA6D;AAClG,SAAO,OAAO;AAAA,IAAI,CAAC,MACjB,EAAE,SAAS,qBACP,EAAE,MAAM,oBAAoB,YAAY,EAAE,YAAY,OAAO,EAAE,OAAO,QAAQ,EAAE,QAAQ,SAAS,EAAE,QAAQ,IAC3G,EAAE,MAAM,YAAY,YAAY,SAAS,EAAE,IAAI,IAAI,MAAM,EAAE,MAAM,KAAK,WAAW,EAAE,IAAI,IAAI,UAAU,iBAAiB,SAAS,EAAE,QAAQ;AAAA,EAC/I;AACF;AAEA,IAAM,YAAY,oBAAI,IAAI,CAAC,OAAO,KAAK,MAAM,OAAO,MAAM,OAAO,MAAM,MAAM,MAAM,MAAM,QAAQ,UAAU,UAAU,OAAO,UAAU,CAAC;AAShI,SAAS,yBAAyB,OAA0D,CAAC,GAGjD;AACjD,QAAM,YAAY,KAAK,aAAa;AACpC,QAAM,SAAS,KAAK,oBAAoB;AACxC,SAAO,OAAO,aAAa,YAAY;AACrC,UAAM,OAAO,QAAQ,KAAK;AAC1B,QAAI,KAAK,SAAS,OAAQ,QAAO,EAAE,SAAS,OAAO,QAAQ,qBAAqB,KAAK,MAAM,gCAAgC;AAC3H,UAAM,SAAS,YAAY,MAAM,YAAY,EAAE,MAAM,YAAY,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,CAAC,UAAU,IAAI,CAAC,CAAC;AAClH,QAAI,OAAO,WAAW,EAAG,QAAO,EAAE,SAAS,MAAM,QAAQ,+EAA0E;AACnI,UAAM,QAAQ,KAAK,YAAY;AAC/B,UAAM,OAAO,OAAO,OAAO,CAAC,MAAM,MAAM,SAAS,CAAC,CAAC,EAAE;AACrD,UAAM,SAAS,OAAO,OAAO;AAC7B,WAAO,UAAU,YACb,EAAE,SAAS,MAAM,QAAQ,mBAAmB,IAAI,IAAI,OAAO,MAAM,sBAAsB,IACvF,EAAE,SAAS,OAAO,QAAQ,wBAAwB,IAAI,IAAI,OAAO,MAAM,sBAAsB;AAAA,EACnG;AACF;","names":[]}
|
|
@@ -1,8 +1,70 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
// src/integrations/index.ts
|
|
2
|
+
import { parseIntegrationToolName } from "@tangle-network/agent-integrations/catalog";
|
|
3
|
+
function resolveIntegrationAction(toolName) {
|
|
4
|
+
let parsed;
|
|
5
|
+
try {
|
|
6
|
+
parsed = parseIntegrationToolName(toolName);
|
|
7
|
+
} catch {
|
|
8
|
+
return void 0;
|
|
9
|
+
}
|
|
10
|
+
if (!parsed.providerId || !parsed.connectorId || !parsed.actionId) return void 0;
|
|
11
|
+
return { ...parsed, path: `${parsed.providerId}.${parsed.connectorId}.${parsed.actionId}` };
|
|
12
|
+
}
|
|
13
|
+
var HubExecClient = class {
|
|
14
|
+
baseUrl;
|
|
15
|
+
bearer;
|
|
16
|
+
fetchImpl;
|
|
17
|
+
constructor(options) {
|
|
18
|
+
if (!options.baseUrl) throw new Error("HubExecClient: baseUrl is required");
|
|
19
|
+
if (!options.bearer) throw new Error("HubExecClient: bearer is required");
|
|
20
|
+
this.baseUrl = options.baseUrl.replace(/\/+$/, "");
|
|
21
|
+
this.bearer = options.bearer;
|
|
22
|
+
this.fetchImpl = options.fetchImpl ?? fetch;
|
|
23
|
+
}
|
|
24
|
+
async exec(input) {
|
|
25
|
+
const response = await this.fetchImpl(`${this.baseUrl}/v1/hub/exec`, {
|
|
26
|
+
method: "POST",
|
|
27
|
+
headers: { Authorization: `Bearer ${this.bearer}`, "Content-Type": "application/json", Accept: "application/json" },
|
|
28
|
+
body: JSON.stringify({ path: input.path, input: input.actionInput, connectionId: input.connectionId })
|
|
29
|
+
});
|
|
30
|
+
const envelope = await this.readEnvelope(response);
|
|
31
|
+
if (response.ok && envelope.success) return { succeeded: true, result: envelope.data?.result };
|
|
32
|
+
return {
|
|
33
|
+
succeeded: false,
|
|
34
|
+
code: envelope.error?.code ?? `HUB_HTTP_${response.status}`,
|
|
35
|
+
message: envelope.error?.message ?? `Hub /exec returned ${response.status}`,
|
|
36
|
+
approval: envelope.error?.details?.approval
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
async readEnvelope(response) {
|
|
40
|
+
const text = await response.text();
|
|
41
|
+
if (!text) return { success: false, error: { code: `HUB_HTTP_${response.status}`, message: `Hub returned ${response.status} with no body` } };
|
|
42
|
+
try {
|
|
43
|
+
return JSON.parse(text);
|
|
44
|
+
} catch {
|
|
45
|
+
return { success: false, error: { code: "HUB_BAD_RESPONSE", message: `Hub returned non-JSON (${response.status}): ${text.slice(0, 200)}` } };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
async function invokeIntegrationHub(input, deps) {
|
|
50
|
+
const env = deps.env ?? process.env;
|
|
51
|
+
const baseUrl = deps.baseUrl ?? env.TANGLE_PLATFORM_URL?.trim();
|
|
52
|
+
if (!baseUrl) return { status: 500, body: { error: "TANGLE_PLATFORM_URL is not configured" } };
|
|
53
|
+
const action = resolveIntegrationAction(input.toolName);
|
|
54
|
+
if (!action) return { status: 400, body: { error: `Unsupported integration tool: ${input.toolName}` } };
|
|
55
|
+
const bearer = await deps.apiKeyResolver(input.userId);
|
|
56
|
+
if (!bearer) return { status: 401, body: { error: "Tangle account not linked \u2014 connect integrations from the app first" } };
|
|
57
|
+
const client = new HubExecClient({ baseUrl, bearer, fetchImpl: deps.fetchImpl });
|
|
58
|
+
const outcome = await client.exec({ path: action.path, actionInput: input.args ?? {} });
|
|
59
|
+
if (outcome.succeeded) {
|
|
60
|
+
return { status: 200, body: { success: true, path: action.path, providerId: action.providerId, action: action.actionId, result: outcome.result } };
|
|
61
|
+
}
|
|
62
|
+
const status = outcome.code === "HUB_APPROVAL_REQUIRED" ? 409 : 502;
|
|
63
|
+
return {
|
|
64
|
+
status,
|
|
65
|
+
body: { success: false, path: action.path, code: outcome.code, error: outcome.message, ...outcome.approval ? { approval: outcome.approval } : {} }
|
|
66
|
+
};
|
|
67
|
+
}
|
|
6
68
|
export {
|
|
7
69
|
HubExecClient,
|
|
8
70
|
invokeIntegrationHub,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/integrations/index.ts"],"sourcesContent":["/**\n * Integration-hub WIRING — the agent→hub invocation path every Tangle agent app\n * forks. The integration ENGINE (catalog, connectors, OAuth, policy) is\n * `@tangle-network/agent-integrations` (a peer dependency); this module is the\n * thin app-side wiring on top: a typed client over the platform hub's\n * `POST /v1/hub/exec`, MCP-tool-name → hub-action-path resolution, and the\n * per-turn invoke flow the `integration_invoke` tool calls.\n *\n * The product supplies its own catalog (which connectors it uses) and its own\n * per-user api-key resolver (the `apiKeyResolver` seam) — this module owns\n * neither credentials nor the action catalog.\n */\nimport { parseIntegrationToolName } from '@tangle-network/agent-integrations/catalog'\n\n/** `{ success: false }` codes the hub returns on `/exec`. */\nexport type HubExecErrorCode =\n | 'HUB_APPROVAL_REQUIRED'\n | 'HUB_POLICY_DENIED'\n | 'HUB_CONNECTION_MISSING'\n | 'HUB_CONNECTION_REVOKED'\n | 'HUB_CONFIG_MISSING'\n | 'HUB_NOT_FOUND'\n | string\n\n/** Outcome of a hub `/exec` call. Callers MUST inspect `succeeded` before\n * reading `result` — a denied or approval-gated write resolves with\n * `succeeded: false` and a populated `code`, never a thrown silent failure. */\nexport type HubExecResult =\n | { succeeded: true; result: unknown }\n | { succeeded: false; code: HubExecErrorCode; message: string; approval?: unknown }\n\n/** Define configuration options for initializing a Hub execution client */\nexport interface HubExecClientOptions {\n /** Platform base URL (e.g. `TANGLE_PLATFORM_URL`). */\n baseUrl: string\n /** Calling user's Tangle API key — the hub principal bearer. */\n bearer: string\n /** Test seam. Defaults to global `fetch`. */\n fetchImpl?: typeof fetch\n}\n\n/** The provider/connector/action a hub action path addresses, plus the dotted\n * `path` the hub `/exec` endpoint expects. */\nexport interface ParsedIntegrationAction {\n providerId: string\n connectorId: string\n actionId: string\n /** `provider.connector.action`. */\n path: string\n}\n\n/**\n * Resolve an MCP tool name (the opaque `int_…` catalog name the agent calls)\n * into the dotted hub action path. Returns `undefined` when the name is not a\n * catalog integration tool, so the chat loop routes non-integration calls\n * elsewhere instead of misrouting them to the hub.\n */\nexport function resolveIntegrationAction(toolName: string): ParsedIntegrationAction | undefined {\n let parsed: { providerId: string; connectorId: string; actionId: string }\n try {\n parsed = parseIntegrationToolName(toolName)\n } catch {\n return undefined\n }\n if (!parsed.providerId || !parsed.connectorId || !parsed.actionId) return undefined\n return { ...parsed, path: `${parsed.providerId}.${parsed.connectorId}.${parsed.actionId}` }\n}\n\ninterface HubEnvelope {\n success: boolean\n data?: { result?: unknown }\n error?: { code?: string; message?: string; details?: { approval?: unknown } }\n}\n\n/** Typed client over the platform hub `/v1/hub/exec`. The hub holds the user's\n * credentials, resolves the connection from the bearer principal, evaluates\n * per-action policy (read → allow, write/destructive → approval), and runs the\n * action server-side. Never throws on a policy block — a gated write is a\n * normal `succeeded: false` outcome. */\nexport class HubExecClient {\n private readonly baseUrl: string\n private readonly bearer: string\n private readonly fetchImpl: typeof fetch\n\n constructor(options: HubExecClientOptions) {\n if (!options.baseUrl) throw new Error('HubExecClient: baseUrl is required')\n if (!options.bearer) throw new Error('HubExecClient: bearer is required')\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '')\n this.bearer = options.bearer\n this.fetchImpl = options.fetchImpl ?? fetch\n }\n\n async exec(input: { path: string; actionInput?: unknown; connectionId?: string }): Promise<HubExecResult> {\n const response = await this.fetchImpl(`${this.baseUrl}/v1/hub/exec`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${this.bearer}`, 'Content-Type': 'application/json', Accept: 'application/json' },\n body: JSON.stringify({ path: input.path, input: input.actionInput, connectionId: input.connectionId }),\n })\n const envelope = await this.readEnvelope(response)\n if (response.ok && envelope.success) return { succeeded: true, result: envelope.data?.result }\n return {\n succeeded: false,\n code: envelope.error?.code ?? `HUB_HTTP_${response.status}`,\n message: envelope.error?.message ?? `Hub /exec returned ${response.status}`,\n approval: envelope.error?.details?.approval,\n }\n }\n\n private async readEnvelope(response: Response): Promise<HubEnvelope> {\n const text = await response.text()\n if (!text) return { success: false, error: { code: `HUB_HTTP_${response.status}`, message: `Hub returned ${response.status} with no body` } }\n try {\n return JSON.parse(text) as HubEnvelope\n } catch {\n return { success: false, error: { code: 'HUB_BAD_RESPONSE', message: `Hub returned non-JSON (${response.status}): ${text.slice(0, 200)}` } }\n }\n }\n}\n\n/** Define input parameters for invoking a hub tool with user ID, tool name, and optional arguments */\nexport interface HubInvokeInput {\n userId: string\n /** The MCP tool name the agent called (`int_<provider>_<connector>_<action>`). */\n toolName: string\n args?: Record<string, unknown>\n}\n/** Describe the outcome of a hub invocation including status and response body */\nexport interface HubInvokeOutcome {\n status: number\n body: Record<string, unknown>\n}\n/** Define dependencies for invoking hub operations including API key resolution and optional configuration */\nexport interface HubInvokeDeps {\n /** Resolve the user's Tangle API key (the hub principal bearer). Required —\n * the product binds its own session-key resolver. Null → user not linked. */\n apiKeyResolver: (userId: string) => Promise<string | null>\n /** Platform base URL. Defaults to `env.TANGLE_PLATFORM_URL`. */\n baseUrl?: string\n fetchImpl?: typeof fetch\n env?: Record<string, string | undefined>\n}\n\n/**\n * Resolve + execute one integration tool call through the hub: resolve the\n * per-user bearer, map the MCP tool name to the hub action path, forward to\n * `/v1/hub/exec`, and shape the route response (200 ok / 401 not-linked /\n * 400 unknown-tool / 409 approval-required / 502 hub-error). A write that's\n * approval-gated surfaces verbatim as 409, never silently executed.\n */\nexport async function invokeIntegrationHub(input: HubInvokeInput, deps: HubInvokeDeps): Promise<HubInvokeOutcome> {\n const env = deps.env ?? (process.env as Record<string, string | undefined>)\n const baseUrl = deps.baseUrl ?? env.TANGLE_PLATFORM_URL?.trim()\n if (!baseUrl) return { status: 500, body: { error: 'TANGLE_PLATFORM_URL is not configured' } }\n\n const action = resolveIntegrationAction(input.toolName)\n if (!action) return { status: 400, body: { error: `Unsupported integration tool: ${input.toolName}` } }\n\n const bearer = await deps.apiKeyResolver(input.userId)\n if (!bearer) return { status: 401, body: { error: 'Tangle account not linked — connect integrations from the app first' } }\n\n const client = new HubExecClient({ baseUrl, bearer, fetchImpl: deps.fetchImpl })\n const outcome = await client.exec({ path: action.path, actionInput: input.args ?? {} })\n\n if (outcome.succeeded) {\n return { status: 200, body: { success: true, path: action.path, providerId: action.providerId, action: action.actionId, result: outcome.result } }\n }\n const status = outcome.code === 'HUB_APPROVAL_REQUIRED' ? 409 : 502\n return {\n status,\n body: { success: false, path: action.path, code: outcome.code, error: outcome.message, ...(outcome.approval ? { approval: outcome.approval } : {}) },\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { e as InteractionRequestWire } from '../contract-CEewO6DI.js';
|
|
2
|
+
export { f as ChatFreeTextField, b as ChatInteraction, a as ChatInteractionField, C as ChatInteractionStatus, d as ChatSelectField, g as ComposerAnswerDelivery, h as INTERACTION_CANCEL_EVENT, i as INTERACTION_EVENT, j as INTERACTION_RESOLVED_EVENT, k as InteractionAnswerValue, I as InteractionAnswers, c as InteractionCancelData, l as InteractionPersistedPart, N as NoticeKind, m as NoticePersistedPart, P as ParseInteractionAnswersResult, n as ParseInteractionResult, o as canTransitionInteractionStatus, p as cancelStatusFor, q as composerAnswerData, r as composerAnswerDeliveries, s as dedupeQuestionInteractionsByContent, t as fieldAcceptsFreeText, u as interactionFromWireRequest, v as interactionPartKey, w as interactionToPersistedPart, x as isRenderableInteractionKind, y as isSafeInteractionFieldKey, z as isTerminalInteractionStatus, A as noticePart, B as noticePartKey, D as parseInteractionAnswers, E as parseInteractionCancel, F as parseInteractionRequest, G as persistedPartToInteraction, H as questionInteractionContentSignature, J as stampInteractionAnswers } from '../contract-CEewO6DI.js';
|
|
3
3
|
import { InteractionOutcome, InteractionData } from '@tangle-network/agent-interface';
|
|
4
4
|
export { InteractionData, InteractionOutcome, InteractionRequest } from '@tangle-network/agent-interface';
|
|
5
5
|
|
|
@@ -146,8 +146,10 @@ interface DurableInteractionRouteArgs extends BeforeInteractionAnswerArgs {
|
|
|
146
146
|
attemptKey: string;
|
|
147
147
|
}
|
|
148
148
|
/** Crash-recoverable persistence lifecycle for the answer route. The product
|
|
149
|
-
* binds this structural port to
|
|
150
|
-
*
|
|
149
|
+
* binds this structural port to its OWN durable store — agent-app ships no
|
|
150
|
+
* implementation (the `/durable-chat` module that used to provide one was
|
|
151
|
+
* removed in 0.44.0 after nine repos produced zero imports of it). Existing
|
|
152
|
+
* `beforeAnswer` behavior remains independent and unchanged. */
|
|
151
153
|
interface DurableInteractionRoutePersistence<TPrepared = unknown> {
|
|
152
154
|
guarantee: 'reconciled' | 'best-effort';
|
|
153
155
|
prepare(args: DurableInteractionRouteArgs): TPrepared | Promise<TPrepared>;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import "../chunk-7LNGJDNA.js";
|
|
2
1
|
import {
|
|
3
2
|
createInteractionAnswerRoute,
|
|
4
3
|
listSessionInteractions,
|
|
5
4
|
mapInteractionRespondFailure,
|
|
6
5
|
respondToSessionInteraction,
|
|
7
6
|
validateInteractionAnswerBody
|
|
8
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-6KMAM7BL.js";
|
|
9
8
|
import {
|
|
10
9
|
INTERACTION_CANCEL_EVENT,
|
|
11
10
|
INTERACTION_EVENT,
|
package/dist/knowledge/index.js
CHANGED
|
@@ -1,7 +1,66 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
// src/knowledge/index.ts
|
|
2
|
+
function clamp(value) {
|
|
3
|
+
if (!Number.isFinite(value)) return 0;
|
|
4
|
+
if (value < 0) return 0;
|
|
5
|
+
if (value > 1) return 1;
|
|
6
|
+
return value;
|
|
7
|
+
}
|
|
8
|
+
function buildKnowledgeRequirements(specs, signals = {}) {
|
|
9
|
+
return specs.map((spec) => {
|
|
10
|
+
const signal = signals[spec.id];
|
|
11
|
+
return {
|
|
12
|
+
id: spec.id,
|
|
13
|
+
description: spec.description,
|
|
14
|
+
requiredFor: spec.requiredFor ?? [],
|
|
15
|
+
category: spec.category,
|
|
16
|
+
acquisitionMode: spec.acquisitionMode,
|
|
17
|
+
importance: spec.importance ?? "blocking",
|
|
18
|
+
freshness: spec.freshness ?? "static",
|
|
19
|
+
sensitivity: spec.sensitivity ?? "private",
|
|
20
|
+
confidenceNeeded: spec.confidenceNeeded ?? 1,
|
|
21
|
+
currentConfidence: clamp(signal?.confidence ?? 0),
|
|
22
|
+
evidenceIds: signal?.evidence ? [signal.evidence] : [],
|
|
23
|
+
fallbackPolicy: spec.acquisitionMode === "ask_user" ? "ask" : "block"
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
async function deriveSignals(specs, ctx) {
|
|
28
|
+
const out = {};
|
|
29
|
+
for (const spec of specs) {
|
|
30
|
+
if (spec.derive) {
|
|
31
|
+
out[spec.id] = { confidence: clamp(await spec.derive(ctx)), evidence: spec.evidence };
|
|
32
|
+
} else if (spec.satisfiedBy) {
|
|
33
|
+
const ok = await evalRule(spec.satisfiedBy, ctx);
|
|
34
|
+
out[spec.id] = ok ? { confidence: 1, evidence: spec.evidence ?? describeRule(spec.satisfiedBy) } : { confidence: 0 };
|
|
35
|
+
} else {
|
|
36
|
+
out[spec.id] = { confidence: 0 };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
async function evalRule(rule, ctx) {
|
|
42
|
+
if ("anyOf" in rule) {
|
|
43
|
+
for (const sub of rule.anyOf) if (await evalRule(sub, ctx)) return true;
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
if ("allOf" in rule) {
|
|
47
|
+
for (const sub of rule.allOf) if (!await evalRule(sub, ctx)) return false;
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
if ("config" in rule) {
|
|
51
|
+
const value = ctx.config(rule.config);
|
|
52
|
+
if (rule.nonEmpty) return Array.isArray(value) ? value.length > 0 : value != null && value !== "";
|
|
53
|
+
return value != null && value !== "" && value !== false;
|
|
54
|
+
}
|
|
55
|
+
const rows = await ctx.count({ table: rule.table, where: rule.where, statusIn: rule.statusIn });
|
|
56
|
+
return rows >= (rule.minRows ?? 1);
|
|
57
|
+
}
|
|
58
|
+
function describeRule(rule) {
|
|
59
|
+
if ("anyOf" in rule) return `anyOf(${rule.anyOf.map(describeRule).join(",")})`;
|
|
60
|
+
if ("allOf" in rule) return `allOf(${rule.allOf.map(describeRule).join(",")})`;
|
|
61
|
+
if ("config" in rule) return `config:${rule.config}`;
|
|
62
|
+
return `${rule.table}${rule.statusIn ? `[${rule.statusIn.join("|")}]` : ""}>=${rule.minRows ?? 1}`;
|
|
63
|
+
}
|
|
5
64
|
export {
|
|
6
65
|
buildKnowledgeRequirements,
|
|
7
66
|
deriveSignals
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/knowledge/index.ts"],"sourcesContent":["/**\n * Declarative knowledge-requirement gate.\n *\n * Every agent product hand-rolls the same pair: a `buildXKnowledgeRequirements`\n * declaring the requirements that gate its control loop, and a\n * `deriveXRuntimeKnowledge` that scores each one from workspace state. Across\n * the fleet those derives are uniformly \"is a config field set\" / \"are there\n * >= N rows in table T (optionally with a status filter)\" / \"any/all of the\n * above\" — data, not logic. This module makes both DATA: a spec list with\n * declarative `satisfiedBy` rules, plus a per-spec `derive` escape hatch for\n * the rare rule a declarative form can't express (e.g. an aggregate over a\n * JSON column).\n *\n * Substrate-free: the only seam is `KnowledgeStateAccessor` (a config lookup +\n * a row count), which the consumer's backend — or `agent-app/preset-cloudflare`\n * — implements. Emits `@tangle-network/agent-eval`'s `KnowledgeRequirement[]`,\n * exactly what the agent-runtime control loop consumes.\n */\n\nimport type {\n KnowledgeAcquisitionMode,\n KnowledgeFreshness,\n KnowledgeImportance,\n KnowledgeRequirement,\n KnowledgeRequirementCategory,\n KnowledgeSensitivity,\n} from '@tangle-network/agent-eval'\n\n/** A declarative rule for satisfying a requirement from workspace state. */\nexport type SatisfiedByRule =\n /** A workspace-config field (dot-path) is set. `nonEmpty` requires a\n * non-empty array/string rather than mere presence. */\n | { config: string; nonEmpty?: boolean }\n /** At least `minRows` (default 1) rows exist in `table` for the workspace,\n * optionally filtered to `statusIn`. `where` names the workspace fk column\n * the accessor scopes on (default: the accessor's convention). */\n | { table: string; where?: string; statusIn?: string[]; minRows?: number }\n | { anyOf: SatisfiedByRule[] }\n | { allOf: SatisfiedByRule[] }\n\n/** Define the criteria and conditions required to satisfy a specific knowledge requirement */\nexport interface KnowledgeRequirementSpec {\n id: string\n description: string\n category: KnowledgeRequirementCategory\n acquisitionMode: KnowledgeAcquisitionMode\n importance?: KnowledgeImportance\n freshness?: KnowledgeFreshness\n sensitivity?: KnowledgeSensitivity\n confidenceNeeded?: number\n requiredFor?: string[]\n /** The data path — evaluated against the `KnowledgeStateAccessor`. */\n satisfiedBy?: SatisfiedByRule\n /** The escape hatch — a code derive for what a rule can't express. Wins\n * over `satisfiedBy` when both are present. Returns confidence in [0, 1]. */\n derive?: (ctx: KnowledgeStateAccessor) => number | Promise<number>\n /** Evidence id attached when satisfied (default: a description of the rule). */\n evidence?: string\n}\n\n/** The single seam a backend implements. `preset-cloudflare` provides a D1\n * implementation; a custom stack supplies its own. */\nexport interface KnowledgeStateAccessor {\n /** Resolve a workspace-config field value (dot-path), or undefined. */\n config: (path: string) => unknown\n /** Count rows in `table` for the active workspace, optionally status-filtered. */\n count: (query: { table: string; where?: string; statusIn?: string[] }) => number | Promise<number>\n}\n\n/** Define a signal representing knowledge with confidence level and optional supporting evidence */\nexport interface KnowledgeSignal {\n confidence: number\n evidence?: string\n}\n\nfunction clamp(value: number): number {\n if (!Number.isFinite(value)) return 0\n if (value < 0) return 0\n if (value > 1) return 1\n return value\n}\n\n/**\n * Map specs -> the runtime's `KnowledgeRequirement[]`, folding in per-spec\n * confidence from `signals` (default 0). Pure + sync: an eval harness can pass\n * hand-authored signals; production passes the output of {@link deriveSignals}.\n */\nexport function buildKnowledgeRequirements(\n specs: KnowledgeRequirementSpec[],\n signals: Record<string, KnowledgeSignal> = {},\n): KnowledgeRequirement[] {\n return specs.map((spec) => {\n const signal = signals[spec.id]\n return {\n id: spec.id,\n description: spec.description,\n requiredFor: spec.requiredFor ?? [],\n category: spec.category,\n acquisitionMode: spec.acquisitionMode,\n importance: spec.importance ?? 'blocking',\n freshness: spec.freshness ?? 'static',\n sensitivity: spec.sensitivity ?? 'private',\n confidenceNeeded: spec.confidenceNeeded ?? 1,\n currentConfidence: clamp(signal?.confidence ?? 0),\n evidenceIds: signal?.evidence ? [signal.evidence] : [],\n fallbackPolicy: spec.acquisitionMode === 'ask_user' ? 'ask' : 'block',\n }\n })\n}\n\n/**\n * Score every spec from workspace state. `derive` (code) wins; otherwise the\n * declarative `satisfiedBy` rule is evaluated through the accessor; a spec with\n * neither scores 0 (an acquisition gate, e.g. `search_web`).\n */\nexport async function deriveSignals(\n specs: KnowledgeRequirementSpec[],\n ctx: KnowledgeStateAccessor,\n): Promise<Record<string, KnowledgeSignal>> {\n const out: Record<string, KnowledgeSignal> = {}\n for (const spec of specs) {\n if (spec.derive) {\n out[spec.id] = { confidence: clamp(await spec.derive(ctx)), evidence: spec.evidence }\n } else if (spec.satisfiedBy) {\n const ok = await evalRule(spec.satisfiedBy, ctx)\n out[spec.id] = ok\n ? { confidence: 1, evidence: spec.evidence ?? describeRule(spec.satisfiedBy) }\n : { confidence: 0 }\n } else {\n out[spec.id] = { confidence: 0 }\n }\n }\n return out\n}\n\nasync function evalRule(rule: SatisfiedByRule, ctx: KnowledgeStateAccessor): Promise<boolean> {\n if ('anyOf' in rule) {\n for (const sub of rule.anyOf) if (await evalRule(sub, ctx)) return true\n return false\n }\n if ('allOf' in rule) {\n for (const sub of rule.allOf) if (!(await evalRule(sub, ctx))) return false\n return true\n }\n if ('config' in rule) {\n const value = ctx.config(rule.config)\n if (rule.nonEmpty) return Array.isArray(value) ? value.length > 0 : value != null && value !== ''\n return value != null && value !== '' && value !== false\n }\n const rows = await ctx.count({ table: rule.table, where: rule.where, statusIn: rule.statusIn })\n return rows >= (rule.minRows ?? 1)\n}\n\nfunction describeRule(rule: SatisfiedByRule): string {\n if ('anyOf' in rule) return `anyOf(${rule.anyOf.map(describeRule).join(',')})`\n if ('allOf' in rule) return `allOf(${rule.allOf.map(describeRule).join(',')})`\n if ('config' in rule) return `config:${rule.config}`\n return `${rule.table}${rule.statusIn ? `[${rule.statusIn.join('|')}]` : ''}>=${rule.minRows ?? 1}`\n}\n"],"mappings":";AA2EA,SAAS,MAAM,OAAuB;AACpC,MAAI,CAAC,OAAO,SAAS,KAAK,EAAG,QAAO;AACpC,MAAI,QAAQ,EAAG,QAAO;AACtB,MAAI,QAAQ,EAAG,QAAO;AACtB,SAAO;AACT;AAOO,SAAS,2BACd,OACA,UAA2C,CAAC,GACpB;AACxB,SAAO,MAAM,IAAI,CAAC,SAAS;AACzB,UAAM,SAAS,QAAQ,KAAK,EAAE;AAC9B,WAAO;AAAA,MACL,IAAI,KAAK;AAAA,MACT,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK,eAAe,CAAC;AAAA,MAClC,UAAU,KAAK;AAAA,MACf,iBAAiB,KAAK;AAAA,MACtB,YAAY,KAAK,cAAc;AAAA,MAC/B,WAAW,KAAK,aAAa;AAAA,MAC7B,aAAa,KAAK,eAAe;AAAA,MACjC,kBAAkB,KAAK,oBAAoB;AAAA,MAC3C,mBAAmB,MAAM,QAAQ,cAAc,CAAC;AAAA,MAChD,aAAa,QAAQ,WAAW,CAAC,OAAO,QAAQ,IAAI,CAAC;AAAA,MACrD,gBAAgB,KAAK,oBAAoB,aAAa,QAAQ;AAAA,IAChE;AAAA,EACF,CAAC;AACH;AAOA,eAAsB,cACpB,OACA,KAC0C;AAC1C,QAAM,MAAuC,CAAC;AAC9C,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,QAAQ;AACf,UAAI,KAAK,EAAE,IAAI,EAAE,YAAY,MAAM,MAAM,KAAK,OAAO,GAAG,CAAC,GAAG,UAAU,KAAK,SAAS;AAAA,IACtF,WAAW,KAAK,aAAa;AAC3B,YAAM,KAAK,MAAM,SAAS,KAAK,aAAa,GAAG;AAC/C,UAAI,KAAK,EAAE,IAAI,KACX,EAAE,YAAY,GAAG,UAAU,KAAK,YAAY,aAAa,KAAK,WAAW,EAAE,IAC3E,EAAE,YAAY,EAAE;AAAA,IACtB,OAAO;AACL,UAAI,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE;AAAA,IACjC;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAe,SAAS,MAAuB,KAA+C;AAC5F,MAAI,WAAW,MAAM;AACnB,eAAW,OAAO,KAAK,MAAO,KAAI,MAAM,SAAS,KAAK,GAAG,EAAG,QAAO;AACnE,WAAO;AAAA,EACT;AACA,MAAI,WAAW,MAAM;AACnB,eAAW,OAAO,KAAK,MAAO,KAAI,CAAE,MAAM,SAAS,KAAK,GAAG,EAAI,QAAO;AACtE,WAAO;AAAA,EACT;AACA,MAAI,YAAY,MAAM;AACpB,UAAM,QAAQ,IAAI,OAAO,KAAK,MAAM;AACpC,QAAI,KAAK,SAAU,QAAO,MAAM,QAAQ,KAAK,IAAI,MAAM,SAAS,IAAI,SAAS,QAAQ,UAAU;AAC/F,WAAO,SAAS,QAAQ,UAAU,MAAM,UAAU;AAAA,EACpD;AACA,QAAM,OAAO,MAAM,IAAI,MAAM,EAAE,OAAO,KAAK,OAAO,OAAO,KAAK,OAAO,UAAU,KAAK,SAAS,CAAC;AAC9F,SAAO,SAAS,KAAK,WAAW;AAClC;AAEA,SAAS,aAAa,MAA+B;AACnD,MAAI,WAAW,KAAM,QAAO,SAAS,KAAK,MAAM,IAAI,YAAY,EAAE,KAAK,GAAG,CAAC;AAC3E,MAAI,WAAW,KAAM,QAAO,SAAS,KAAK,MAAM,IAAI,YAAY,EAAE,KAAK,GAAG,CAAC;AAC3E,MAAI,YAAY,KAAM,QAAO,UAAU,KAAK,MAAM;AAClD,SAAO,GAAG,KAAK,KAAK,GAAG,KAAK,WAAW,IAAI,KAAK,SAAS,KAAK,GAAG,CAAC,MAAM,EAAE,KAAK,KAAK,WAAW,CAAC;AAClG;","names":[]}
|
|
@@ -2,7 +2,7 @@ import { KnowledgeResearchLoopContext, AddSourceTextInput, SourceAdapter, RunKno
|
|
|
2
2
|
import { KnowledgeSourceSpec, AgentKnowledgeConfig } from '../config/index.js';
|
|
3
3
|
import '../knowledge/index.js';
|
|
4
4
|
import '@tangle-network/agent-eval';
|
|
5
|
-
import '../model-
|
|
5
|
+
import '../model-CdCDfBA9.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* `@tangle-network/agent-app/knowledge-loop` — wire the declarative
|