@inneranimalmedia/agentsam-sdk 2.6.3 → 2.6.4
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/AGENTSAM.md +6 -0
- package/README.md +16 -1
- package/bin/agentsam +16 -1
- package/docs/BRAND_INTELLIGENCE.md +1 -1
- package/docs/architecture/AGENTSAM_DISTRIBUTION_OWNERSHIP.md +176 -0
- package/docs/architecture/AGENTSAM_GO_RUNTIME.md +282 -0
- package/docs/architecture/CODEBASEINDEX_GUIDED_PATH.md +202 -0
- package/docs/architecture/FS_E2E_CLOSURE_RECEIPT.md +59 -0
- package/docs/architecture/LOCAL_FS_AUTHORITY.md +38 -0
- package/docs/architecture/LOCAL_STUDIO_CLOUDFLARE_OAUTH.md +28 -0
- package/docs/architecture/PLAN_CLI_AND_LOCAL_STUDIO_DESKTOP.md +96 -0
- package/docs/architecture/SAM_ACTIVITY_RECOVERY_RECEIPT.md +39 -0
- package/docs/architecture/SAM_DECISION_WORK_RECEIPT.md +54 -0
- package/docs/architecture/SAM_KERNEL.md +181 -0
- package/docs/architecture/SAM_MACHINE_NORMALIZATION_PRECOMMIT_REPORT.md +208 -0
- package/docs/architecture/SLASH_SKILLS_PORTABLE.md +116 -0
- package/docs/architecture/fs-e2e-receipt.latest.json +42 -0
- package/docs/architecture/previews/codebaseindex-guided-path/CODEBASEINDEX_GUIDED_PATH.md +202 -0
- package/docs/architecture/previews/codebaseindex-guided-path/index.html +321 -0
- package/migrations/d1/0010_portable_tickets_memory.sql +140 -0
- package/migrations/d1/0011_agentsam_skill_v2.sql +185 -0
- package/migrations/d1/0011b_agentsam_skill_v2_cutover.sql +22 -0
- package/migrations/d1/0011c_agentsam_skill_v2_backfill.sql +76 -0
- package/migrations/d1/0011d_agentsam_skill_v2_retrieval_revisions.sql +50 -0
- package/migrations/d1/0012_agentsam_tools_required_seed.sql +67 -0
- package/migrations/d1/0013_identity_oauth_states.sql +15 -0
- package/migrations/d1/0014_auth_event_log.sql +20 -0
- package/migrations/d1/0015_identity_oauth_state_app_id.sql +3 -0
- package/migrations/d1/README_PORTABLE_CONTROL_PLANE.md +16 -0
- package/migrations/sqlite/agentsam_skill_retrieval.portable.sql +42 -0
- package/package.json +19 -4
- package/packages/agentsam-contracts/src/errors.ts +16 -0
- package/packages/agentsam-errors/src/envelope.js +53 -0
- package/packages/agentsam-errors/src/index.js +1 -0
- package/packages/agentsam-errors/src/recovery.js +301 -0
- package/packages/agentsam-knowledge/src/providers/index.js +18 -6
- package/packages/connectors/cloudflare/src/routes.js +9 -0
- package/packages/connectors/cloudflare/tests/connector.test.mjs +26 -1
- package/packages/identity/.agentsam/features/oauth-login-portal/agentsam.feature.json +1 -1
- package/packages/identity/.agentsam/features/oauth-login-portal/routes.json +11 -2
- package/packages/identity/docs/PORTABLE_IDENTITY_ARCHITECTURE.md +50 -0
- package/packages/identity/migrations/D1_SCHEMA_MAPPING.md +31 -0
- package/packages/identity/migrations/sqlite/001_identity_core.sql +99 -0
- package/packages/identity/migrations/sqlite/002_identity_oauth_client.sql +38 -0
- package/packages/identity/migrations/sqlite/003_identity_oauth_server.sql +64 -0
- package/packages/identity/package.json +2 -2
- package/packages/identity/src/adapters/cloudflare-d1/index.js +122 -22
- package/packages/identity/src/adapters/sqlite/index.js +319 -0
- package/packages/identity/src/app/verify-app.js +95 -0
- package/packages/identity/src/contracts/identity-store.js +115 -0
- package/packages/identity/src/contracts/route-ids.js +30 -0
- package/packages/identity/src/contracts/route-projection.js +218 -0
- package/packages/identity/src/contracts/routes.js +11 -0
- package/packages/identity/src/core/browser-paths.js +4 -5
- package/packages/identity/src/core/constants.js +13 -8
- package/packages/identity/src/core/session-policy.js +32 -0
- package/packages/identity/src/frontend/auth-portal/pages/login.html +10 -10
- package/packages/identity/src/frontend/auth-portal/pages/reset.html +3 -3
- package/packages/identity/src/frontend/auth-portal/pages/signup.html +3 -3
- package/packages/identity/src/frontend/auth-portal/preview/dashboard-stub.html +1 -1
- package/packages/identity/src/index.js +25 -0
- package/packages/identity/src/oauth/README.md +10 -4
- package/packages/identity/src/oauth/credentials.js +20 -13
- package/packages/identity/src/oauth/finalize-inbound.js +1 -1
- package/packages/identity/src/oauth/iam-platform.js +8 -7
- package/packages/identity/src/oauth/redirect-paths.js +27 -36
- package/packages/identity/src/server/identity-service.js +30 -13
- package/packages/identity/src/server/mount-policy.js +30 -0
- package/packages/identity/src/server/post-auth.js +79 -0
- package/packages/identity/src/server/worker-router.js +104 -72
- package/packages/identity/tests/finalize-inbound-oauth.test.mjs +6 -6
- package/packages/identity/tests/iam-provider.test.mjs +1 -1
- package/packages/identity/tests/identity-service.test.mjs +36 -5
- package/packages/identity/tests/oauth-credentials.test.mjs +3 -1
- package/packages/identity/tests/portable-identity-architecture.test.mjs +157 -0
- package/packages/identity/tests/session-routes-policy.test.mjs +21 -0
- package/packages/theme-church-site/package.json +2 -1
- package/packages/theme-church-site/src/index.js +1 -0
- package/packages/theme-companions-site/package.json +2 -1
- package/packages/theme-companions-site/src/index.js +1 -0
- package/packages/theme-floors-site/package.json +2 -1
- package/packages/theme-floors-site/src/index.js +1 -0
- package/packages/theme-fuelnfree-site/package.json +2 -1
- package/packages/theme-fuelnfree-site/src/index.js +1 -0
- package/packages/theme-handyman-site/package.json +2 -1
- package/packages/theme-handyman-site/src/index.js +1 -0
- package/packages/theme-insurance-site/package.json +2 -1
- package/packages/theme-insurance-site/src/index.js +1 -0
- package/packages/theme-shinshu-site/package.json +2 -1
- package/packages/theme-shinshu-site/src/index.js +1 -0
- package/protocol/apps/agentsam.app.v1.schema.json +51 -0
- package/protocol/brand/brandpack.v1.schema.json +43 -0
- package/protocol/credentials/issue.v1.schema.json +38 -0
- package/protocol/database/connection.v1.schema.json +41 -0
- package/protocol/embeddings/embedding-profile.v1.schema.json +20 -0
- package/protocol/errors/error-envelope.schema.json +135 -1
- package/protocol/errors/recovery.v1.schema.json +50 -0
- package/protocol/runtime/workspace-fs.v1.schema.json +71 -0
- package/protocol/sam/activity.v1.schema.json +48 -0
- package/protocol/sam/answer.v1.schema.json +35 -0
- package/protocol/sam/calibration.v1.schema.json +21 -0
- package/protocol/sam/decision-receipt.v1.schema.json +29 -0
- package/protocol/sam/evaluation.v1.schema.json +19 -0
- package/protocol/sam/operation.schema.json +66 -0
- package/protocol/sam/outcome.v1.schema.json +36 -0
- package/protocol/sam/question.v1.schema.json +26 -0
- package/protocol/sam/registry.seed.json +153 -0
- package/protocol/sam/result.schema.json +53 -0
- package/protocol/sam/state.v1.schema.json +23 -0
- package/protocol/skills/agentsam.interaction.v1.schema.json +50 -0
- package/protocol/skills/agentsam.skill.v1.schema.json +57 -0
- package/protocol/ui/icon-registry.mjs +226 -0
- package/protocol/ui/icon.v1.schema.json +51 -0
- package/skills/README.md +22 -9
- package/skills/agentsam-codebaseindex/SKILL.md +225 -0
- package/skills/catalog.json +14 -0
- package/src/cli/command-catalog.js +130 -0
- package/src/cli/dispatch.js +48 -0
- package/src/cli.js +43 -1
- package/src/commands/api-key.js +244 -0
- package/src/commands/app.js +60 -28
- package/src/commands/brand.js +17 -19
- package/src/commands/codebaseindex.js +688 -0
- package/src/commands/env.js +152 -25
- package/src/commands/go.js +366 -53
- package/src/commands/interaction-clack.js +115 -0
- package/src/commands/models.js +1 -1
- package/src/commands/providers.js +62 -14
- package/src/commands/shell.js +43 -2
- package/src/commands/skill.js +248 -0
- package/src/commands/skills.js +1 -1
- package/src/commands/start-local.js +4 -0
- package/src/commands/whoami.js +90 -18
- package/src/go/build.js +229 -39
- package/src/go/cloudflare.js +506 -105
- package/src/go/container.js +120 -0
- package/src/go/contract.js +9 -4
- package/src/go/discover.js +149 -33
- package/src/go/index.js +15 -3
- package/src/go/native-probe-runner.mjs +119 -0
- package/src/go/{registry.js → official-registry.js} +64 -7
- package/src/go/official-release.js +10 -0
- package/src/go/receipts.js +77 -10
- package/src/go/verify.js +9 -2
- package/src/index.js +27 -0
- package/src/indexing/ingest/discover-models.js +298 -0
- package/src/indexing/ingest/inventory.js +243 -0
- package/src/indexing/ingest/job-graph.js +181 -0
- package/src/indexing/ingest/materials.js +210 -0
- package/src/lib/provider-credentials.js +63 -21
- package/src/lib/slash-commands.js +1 -0
- package/src/local-fs/capability.js +121 -0
- package/src/local-fs/freshness.js +75 -0
- package/src/local-fs/index.js +385 -0
- package/src/local-fs/paths.js +100 -0
- package/src/local-pty/server.js +295 -19
- package/src/mcp/client.js +2 -2
- package/src/models/ai-access-onboarding.js +112 -0
- package/src/models/discovery.js +10 -2
- package/src/models/inventory-core.js +9 -1
- package/src/sam/activity/index.js +183 -0
- package/src/sam/client.js +252 -0
- package/src/sam/decision/calibration.js +109 -0
- package/src/sam/decision/confidence.js +126 -0
- package/src/sam/decision/evaluate.js +157 -0
- package/src/sam/decision/evaluators/deterministic.js +341 -0
- package/src/sam/decision/evaluators/heuristic.js +61 -0
- package/src/sam/decision/evaluators/select.js +50 -0
- package/src/sam/decision/evaluators/semantic.js +149 -0
- package/src/sam/decision/hierarchical.js +61 -0
- package/src/sam/decision/index.js +53 -0
- package/src/sam/decision/policy.js +86 -0
- package/src/sam/decision/questions.js +120 -0
- package/src/sam/decision/receipt.js +148 -0
- package/src/sam/decision/state.js +117 -0
- package/src/sam/decision/types.js +22 -0
- package/src/sam/decision/validate.js +200 -0
- package/src/sam/define.js +51 -0
- package/src/sam/index.js +65 -0
- package/src/sam/operations/brand-scan.js +62 -0
- package/src/sam/operations/cad-blender-inspect.js +36 -0
- package/src/sam/operations/codebaseindex-ingest.js +49 -0
- package/src/sam/operations/decision-evaluate.js +59 -0
- package/src/sam/operations/planning-astar.js +77 -0
- package/src/sam/operations/planning-goap.js +60 -0
- package/src/sam/operations/repository-inspect.js +72 -0
- package/src/sam/operations/security-scan.js +33 -0
- package/src/sam/operations/terminal-exec.js +29 -0
- package/src/sam/planning/astar.js +311 -0
- package/src/sam/planning/goap.js +177 -0
- package/src/sam/planning/index.js +21 -0
- package/src/sam/planning/state.js +84 -0
- package/src/sam/registry.js +48 -0
- package/src/sam/result.js +77 -0
- package/src/sam/seed.js +44 -0
- package/src/sam/types.js +91 -0
- package/src/skills/catalog.js +64 -0
- package/src/skills/content-resolver.js +124 -0
- package/src/skills/hosted-store.js +37 -0
- package/src/skills/index.js +29 -64
- package/src/skills/interaction.js +102 -0
- package/src/skills/local-store.js +228 -0
- package/src/skills/manifest.js +104 -0
- package/src/skills/metrics.js +31 -0
- package/src/skills/registry.js +184 -0
- package/src/skills/runtime.js +287 -0
- package/src/skills/slash.js +44 -0
- package/src/ui/cli/help.js +94 -101
- package/test/cli/api-key-env-whoami.test.mjs +129 -0
- package/test/cli/codebaseindex-plan-ux.test.mjs +37 -0
- package/test/cli/go.test.mjs +62 -5
- package/test/cli/skill-npm-and-env.test.mjs +52 -0
- package/test/cli/wireframes-go-registry.test.mjs +87 -2
- package/test/go/build-source-identity.test.mjs +31 -0
- package/test/go/cloudflare-probe.test.mjs +274 -10
- package/test/go/distribution.test.mjs +28 -0
- package/test/integration/ai-access-onboarding.test.mjs +47 -0
- package/test/integration/cli-help.test.mjs +1 -1
- package/test/integration/cms-site-tenancy-contract.test.mjs +6 -6
- package/test/integration/codebaseindex-ingest.test.mjs +166 -0
- package/test/integration/icon-registry.test.mjs +67 -0
- package/test/integration/ingest-discover-models.test.mjs +30 -0
- package/test/integration/install-script.test.mjs +12 -9
- package/test/integration/local-fs.test.mjs +113 -0
- package/test/integration/provider-env-cli.test.mjs +2 -1
- package/test/integration/sam-activity-recovery.test.mjs +147 -0
- package/test/integration/sam-decision.test.mjs +584 -0
- package/test/integration/sam-kernel.test.mjs +99 -0
- package/test/integration/sam-planning-astar.test.mjs +279 -0
- package/test/integration/skill-runtime.test.mjs +240 -0
- package/test/integration/studio-fs-pty-e2e.test.mjs +294 -0
- package/test/models.test.mjs +14 -7
- package/test/shell.test.mjs +4 -4
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const INNERANIMALMEDIA_OFFICIAL_RELEASE_ENV =
|
|
2
|
+
'AGENTSAM_INNERANIMALMEDIA_OFFICIAL_RELEASE';
|
|
3
|
+
|
|
4
|
+
export const LEGACY_IAM_OFFICIAL_RELEASE_ENV =
|
|
5
|
+
'AGENTSAM_IAM_OFFICIAL_RELEASE';
|
|
6
|
+
|
|
7
|
+
export function innerAnimalMediaOfficialReleaseEnabled(env = process.env) {
|
|
8
|
+
return env?.[INNERANIMALMEDIA_OFFICIAL_RELEASE_ENV] === '1'
|
|
9
|
+
|| env?.[LEGACY_IAM_OFFICIAL_RELEASE_ENV] === '1';
|
|
10
|
+
}
|
package/src/go/receipts.js
CHANGED
|
@@ -10,18 +10,40 @@ export function goStateDir(productRoot) {
|
|
|
10
10
|
export function writeGoBuildReceipt(productRoot, receipt) {
|
|
11
11
|
const dir = goStateDir(productRoot);
|
|
12
12
|
const file = path.join(dir, 'latest.build-receipt.json');
|
|
13
|
-
fs.writeFileSync(file,
|
|
13
|
+
fs.writeFileSync(file, JSON.stringify(receipt, null, 2) + '\n');
|
|
14
14
|
return file;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export function writeDeploymentReceipt(productRoot, receipt) {
|
|
18
18
|
const dir = goStateDir(productRoot);
|
|
19
19
|
const file = path.join(dir, 'latest.deployment-receipt.json');
|
|
20
|
+
const payload = { schema: 'agentsam.deployment-receipt.v1', ...receipt };
|
|
21
|
+
fs.writeFileSync(file, JSON.stringify(payload, null, 2) + '\n');
|
|
22
|
+
return file;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function writeDeploymentValidationReceipt(productRoot, receipt) {
|
|
26
|
+
const dir = goStateDir(productRoot);
|
|
27
|
+
const file = path.join(dir, 'latest.deployment-validation-receipt.json');
|
|
20
28
|
const payload = {
|
|
21
|
-
schema: 'agentsam.deployment-receipt.v1',
|
|
29
|
+
schema: 'agentsam.deployment-validation-receipt.v1',
|
|
22
30
|
...receipt,
|
|
23
31
|
};
|
|
24
|
-
fs.writeFileSync(file,
|
|
32
|
+
fs.writeFileSync(file, JSON.stringify(payload, null, 2) + '\n');
|
|
33
|
+
return file;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function writeProductValidationLocal(productRoot, row) {
|
|
37
|
+
const dir = goStateDir(productRoot);
|
|
38
|
+
const file = path.join(dir, 'product.validation-registry.json');
|
|
39
|
+
const payload = {
|
|
40
|
+
schema: 'agentsam.product-validation-registry.v1',
|
|
41
|
+
registry: 'agentsam_products',
|
|
42
|
+
authority: 'local_validation',
|
|
43
|
+
row,
|
|
44
|
+
written_at: new Date().toISOString(),
|
|
45
|
+
};
|
|
46
|
+
fs.writeFileSync(file, JSON.stringify(payload, null, 2) + '\n');
|
|
25
47
|
return file;
|
|
26
48
|
}
|
|
27
49
|
|
|
@@ -31,11 +53,11 @@ export function writeProductRegistryLocal(productRoot, row) {
|
|
|
31
53
|
const payload = {
|
|
32
54
|
schema: 'agentsam.product-local-registry.v1',
|
|
33
55
|
registry: 'agentsam_products',
|
|
34
|
-
note: 'Local projection
|
|
56
|
+
note: 'Local AgentSam projection. InnerAnimalMedia D1 registration is a separate explicit official-release operation.',
|
|
35
57
|
row,
|
|
36
58
|
written_at: new Date().toISOString(),
|
|
37
59
|
};
|
|
38
|
-
fs.writeFileSync(file,
|
|
60
|
+
fs.writeFileSync(file, JSON.stringify(payload, null, 2) + '\n');
|
|
39
61
|
return file;
|
|
40
62
|
}
|
|
41
63
|
|
|
@@ -44,20 +66,43 @@ export function readLatestStatus(productRoot) {
|
|
|
44
66
|
const buildPath = path.join(dir, 'latest.build-receipt.json');
|
|
45
67
|
const deployPath = path.join(dir, 'latest.deployment-receipt.json');
|
|
46
68
|
const productPath = path.join(dir, 'product.registry.json');
|
|
69
|
+
const validationPath = path.join(dir, 'latest.deployment-validation-receipt.json');
|
|
70
|
+
const validationProductPath = path.join(dir, 'product.validation-registry.json');
|
|
47
71
|
return {
|
|
48
72
|
build: fs.existsSync(buildPath) ? JSON.parse(fs.readFileSync(buildPath, 'utf8')) : null,
|
|
49
73
|
deployment: fs.existsSync(deployPath) ? JSON.parse(fs.readFileSync(deployPath, 'utf8')) : null,
|
|
50
74
|
product: fs.existsSync(productPath) ? JSON.parse(fs.readFileSync(productPath, 'utf8')) : null,
|
|
75
|
+
validation: fs.existsSync(validationPath) ? JSON.parse(fs.readFileSync(validationPath, 'utf8')) : null,
|
|
76
|
+
validation_product: fs.existsSync(validationProductPath)
|
|
77
|
+
? JSON.parse(fs.readFileSync(validationProductPath, 'utf8'))
|
|
78
|
+
: null,
|
|
51
79
|
};
|
|
52
80
|
}
|
|
53
81
|
|
|
54
|
-
export function buildProductRow({
|
|
82
|
+
export function buildProductRow({
|
|
83
|
+
product,
|
|
84
|
+
repositoryId,
|
|
85
|
+
commit,
|
|
86
|
+
sourceIdentity = null,
|
|
87
|
+
packageName = '@inneranimalmedia/agentsam-go-worker',
|
|
88
|
+
packageVersion = '0.1.0',
|
|
89
|
+
cloudflareAccount = null,
|
|
90
|
+
url,
|
|
91
|
+
health,
|
|
92
|
+
workerDeploymentId = null,
|
|
93
|
+
workerVersionId = null,
|
|
94
|
+
artifactDigest = null,
|
|
95
|
+
containerDigest = null,
|
|
96
|
+
}) {
|
|
55
97
|
return {
|
|
56
98
|
slug: product,
|
|
57
99
|
kind: 'service',
|
|
58
100
|
name: product,
|
|
59
101
|
status: health === 'healthy' ? 'deployed' : (health === 'pending' ? 'built' : 'degraded'),
|
|
60
102
|
repository_id: repositoryId || null,
|
|
103
|
+
canonical_path: 'apps/agentsam-go-worker',
|
|
104
|
+
package_name: packageName,
|
|
105
|
+
version: packageVersion,
|
|
61
106
|
metadata: {
|
|
62
107
|
runtime: 'go',
|
|
63
108
|
deployment: {
|
|
@@ -65,12 +110,34 @@ export function buildProductRow({ product, repositoryId, commit, url, health })
|
|
|
65
110
|
mode: 'worker-container',
|
|
66
111
|
url: url || null,
|
|
67
112
|
health: health || null,
|
|
113
|
+
worker_deployment_id: workerDeploymentId,
|
|
114
|
+
worker_version_id: workerVersionId,
|
|
115
|
+
artifact_digest: artifactDigest,
|
|
116
|
+
container_image_digest: containerDigest,
|
|
117
|
+
cloudflare_account: cloudflareAccount,
|
|
118
|
+
},
|
|
119
|
+
source: {
|
|
120
|
+
identity: sourceIdentity,
|
|
121
|
+
commit: commit || null,
|
|
122
|
+
package_name: packageName,
|
|
123
|
+
package_version: packageVersion,
|
|
68
124
|
},
|
|
69
|
-
source: { commit: commit || null },
|
|
70
125
|
relationships: [
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
126
|
+
repositoryId
|
|
127
|
+
? { type: 'source_repository', target: repositoryId }
|
|
128
|
+
: { type: 'source_package', target: packageName },
|
|
129
|
+
{
|
|
130
|
+
type: 'runtime',
|
|
131
|
+
target: 'go',
|
|
132
|
+
target_type: 'runtime',
|
|
133
|
+
relationship_type: 'runs_on',
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
type: 'edge',
|
|
137
|
+
target: product,
|
|
138
|
+
target_type: 'cloudflare_worker',
|
|
139
|
+
relationship_type: 'deployed_as',
|
|
140
|
+
},
|
|
74
141
|
],
|
|
75
142
|
},
|
|
76
143
|
};
|
package/src/go/verify.js
CHANGED
|
@@ -4,18 +4,25 @@ import { runGoTests, runGoVet } from './build.js';
|
|
|
4
4
|
|
|
5
5
|
export async function verifyGoProduct({
|
|
6
6
|
productRoot,
|
|
7
|
+
stateRoot = productRoot,
|
|
7
8
|
runtimeRoot,
|
|
8
9
|
url = null,
|
|
9
10
|
fetchImpl = globalThis.fetch,
|
|
10
11
|
skipLive = false,
|
|
11
12
|
} = {}) {
|
|
12
|
-
const status = readLatestStatus(
|
|
13
|
+
const status = readLatestStatus(stateRoot);
|
|
13
14
|
const tests = runtimeRoot ? runGoTests(runtimeRoot) : { ok: false, error: 'no_runtime' };
|
|
14
15
|
const vet = runtimeRoot ? runGoVet(runtimeRoot) : { ok: false, error: 'no_runtime' };
|
|
15
16
|
const liveUrl = url || status.deployment?.url || null;
|
|
16
17
|
let live = { skipped: true, ok: false };
|
|
17
18
|
if (!skipLive && liveUrl) {
|
|
18
|
-
live = await probeGoDeployment(liveUrl, {
|
|
19
|
+
live = await probeGoDeployment(liveUrl, {
|
|
20
|
+
fetchImpl,
|
|
21
|
+
expectedSource: status.deployment?.source_identity || status.build?.source?.identity || null,
|
|
22
|
+
expectedSourceCommit: status.deployment?.source_commit || status.build?.source?.commit || null,
|
|
23
|
+
expectedTarget: 'cloudflare',
|
|
24
|
+
edge: true,
|
|
25
|
+
});
|
|
19
26
|
}
|
|
20
27
|
|
|
21
28
|
const ok = Boolean(tests.ok && vet.ok && (skipLive || !liveUrl || live.ok));
|
package/src/index.js
CHANGED
|
@@ -3,6 +3,27 @@
|
|
|
3
3
|
import pkg from '../package.json' with { type: 'json' };
|
|
4
4
|
|
|
5
5
|
export { AgentSam } from './AgentSam.js';
|
|
6
|
+
export {
|
|
7
|
+
SAM_RESULT_SCHEMA,
|
|
8
|
+
SAM_EXPANSION,
|
|
9
|
+
defineSamOperation,
|
|
10
|
+
registerSamOperation,
|
|
11
|
+
getSamOperation,
|
|
12
|
+
listSamOperations,
|
|
13
|
+
toSamOperationCard,
|
|
14
|
+
buildSamResult,
|
|
15
|
+
AgentSamClient,
|
|
16
|
+
createAgentSamClient,
|
|
17
|
+
ensureSeedOperations,
|
|
18
|
+
SEED_OPERATIONS,
|
|
19
|
+
} from './sam/index.js';
|
|
20
|
+
export {
|
|
21
|
+
CLI_COMMAND_CATALOG,
|
|
22
|
+
getCliCommand,
|
|
23
|
+
listCliCommands,
|
|
24
|
+
printAssistTip,
|
|
25
|
+
suggestCliCommands,
|
|
26
|
+
} from './cli/command-catalog.js';
|
|
6
27
|
export { routeIntent } from './lib/router.js';
|
|
7
28
|
export { searchToolCards, toToolCard, hydrateToolSchemas } from './tools/index.js';
|
|
8
29
|
export {
|
|
@@ -130,6 +151,12 @@ export {
|
|
|
130
151
|
fingerprintError,
|
|
131
152
|
shouldRetry,
|
|
132
153
|
retryDelayMs,
|
|
154
|
+
planRecovery,
|
|
155
|
+
inferFailureClass,
|
|
156
|
+
inferSideEffectState,
|
|
157
|
+
FAILURE_CLASS,
|
|
158
|
+
SIDE_EFFECT_STATE,
|
|
159
|
+
RECOVERY_SCHEMA,
|
|
133
160
|
toHttpError,
|
|
134
161
|
fromHttpError,
|
|
135
162
|
renderError,
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discover embedding models from the user's configured credentials.
|
|
3
|
+
*
|
|
4
|
+
* Authority order for the picker:
|
|
5
|
+
* 1. Credential-scoped cloud providers (OpenAI, Gemini, Cloudflare Workers AI)
|
|
6
|
+
* 2. Optional local Ollama inventory (offer only — never required, never SSOT)
|
|
7
|
+
* 3. Always "none" (AST/text only)
|
|
8
|
+
*
|
|
9
|
+
* Dimensions are profile fingerprints for the chosen provider/model — not "Ollama truth."
|
|
10
|
+
* Regex/name heuristics are hints until a real embed/adapter reports length.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { collectModelsStatus } from '../../commands/models.js';
|
|
14
|
+
import { resolveOllamaConfig, probeOllama, probeOllamaModel } from '../../commands/ollama.js';
|
|
15
|
+
import { resolveProviderCredential } from '../../lib/provider-credentials.js';
|
|
16
|
+
import { createProviderRegistry } from '../../../packages/agentsam-knowledge/src/providers/index.js';
|
|
17
|
+
|
|
18
|
+
function clean(value) {
|
|
19
|
+
return value == null ? '' : String(value).trim();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Known Workers AI / Vectorize-friendly embed dims (hint until first embed probes). */
|
|
23
|
+
const WORKERS_AI_EMBED_DIMS = Object.freeze({
|
|
24
|
+
'@cf/baai/bge-small-en-v1.5': 384,
|
|
25
|
+
'@cf/baai/bge-base-en-v1.5': 768,
|
|
26
|
+
'@cf/baai/bge-large-en-v1.5': 1024,
|
|
27
|
+
'@cf/baai/bge-m3': 1024,
|
|
28
|
+
'@cf/google/embeddinggemma-300m': 768,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
function looksLikeEmbedModel(name) {
|
|
32
|
+
const id = clean(name).toLowerCase();
|
|
33
|
+
if (!id) return false;
|
|
34
|
+
return /embed|bge-|e5-|gte-|minilm|mxbai-embed|nomic-embed|snowflake-arctic-embed/i.test(id);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Hint dimensions for a provider/model. Not authoritative — adapters may probe.
|
|
39
|
+
*/
|
|
40
|
+
function defaultDimensions(provider, model) {
|
|
41
|
+
const id = clean(model).toLowerCase();
|
|
42
|
+
if (provider === 'openai') {
|
|
43
|
+
if (id.includes('large')) return 3072;
|
|
44
|
+
if (id.includes('small')) return 1536;
|
|
45
|
+
return 1536;
|
|
46
|
+
}
|
|
47
|
+
if (provider === 'gemini') {
|
|
48
|
+
return 768;
|
|
49
|
+
}
|
|
50
|
+
if (provider === 'workers-ai' || provider === 'cloudflare') {
|
|
51
|
+
if (WORKERS_AI_EMBED_DIMS[clean(model)]) return WORKERS_AI_EMBED_DIMS[clean(model)];
|
|
52
|
+
if (id.includes('small')) return 384;
|
|
53
|
+
if (id.includes('large') || id.includes('bge-m3')) return 1024;
|
|
54
|
+
return 768;
|
|
55
|
+
}
|
|
56
|
+
if (provider === 'ollama') {
|
|
57
|
+
if (id.includes('mxbai-embed-large')) return 1024;
|
|
58
|
+
if (id.includes('nomic-embed')) return 768;
|
|
59
|
+
return 1024;
|
|
60
|
+
}
|
|
61
|
+
return 768;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Encode a selectable embedding profile for clack / CLI.
|
|
66
|
+
* Format: provider|model|dimensions (pipe — models may contain colons)
|
|
67
|
+
*/
|
|
68
|
+
export function encodeEmbeddingChoice(provider, model, dimensions) {
|
|
69
|
+
return `${provider}|${model}|${dimensions}`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @param {string} value
|
|
74
|
+
*/
|
|
75
|
+
export function parseEmbeddingChoice(value) {
|
|
76
|
+
if (!value || value === 'none') {
|
|
77
|
+
return { provider: 'none', model: 'none', revision: '1', dimensions: 0, parameters: {} };
|
|
78
|
+
}
|
|
79
|
+
// New encoding: provider|model|dims
|
|
80
|
+
if (String(value).includes('|')) {
|
|
81
|
+
const [provider, model, dims] = String(value).split('|');
|
|
82
|
+
return {
|
|
83
|
+
provider: clean(provider),
|
|
84
|
+
model: clean(model),
|
|
85
|
+
revision: '1',
|
|
86
|
+
dimensions: Number(dims) || defaultDimensions(provider, model),
|
|
87
|
+
parameters: provider === 'gemini' ? { task: 'code retrieval' } : {},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
// Legacy encoding used briefly: provider:model:dims (breaks on model ids with colons)
|
|
91
|
+
const parts = String(value).split(':');
|
|
92
|
+
if (parts.length >= 3) {
|
|
93
|
+
const provider = parts[0];
|
|
94
|
+
const dims = parts[parts.length - 1];
|
|
95
|
+
const model = parts.slice(1, -1).join(':');
|
|
96
|
+
return {
|
|
97
|
+
provider: clean(provider),
|
|
98
|
+
model: clean(model),
|
|
99
|
+
revision: '1',
|
|
100
|
+
dimensions: Number(dims) || defaultDimensions(provider, model),
|
|
101
|
+
parameters: provider === 'gemini' ? { task: 'code retrieval' } : {},
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
throw new Error(`invalid_embedding_choice:${value}`);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Build embedding select options from live discovery.
|
|
109
|
+
* Always offers "none" (AST/text only). Ollama entries appear only when online (optional).
|
|
110
|
+
*
|
|
111
|
+
* @param {object} [options]
|
|
112
|
+
* @returns {Promise<{ options: object[], inventory: object, assistModels: object[] }>}
|
|
113
|
+
*/
|
|
114
|
+
export async function discoverIngestModelOptions(options = {}) {
|
|
115
|
+
const env = options.env || process.env;
|
|
116
|
+
const status = await collectModelsStatus({
|
|
117
|
+
env,
|
|
118
|
+
home: options.home,
|
|
119
|
+
discoverRemote: options.discoverRemote !== false,
|
|
120
|
+
includeLocal: true,
|
|
121
|
+
// Keep CF embed models; chat allowlist must not hide Vectorize options.
|
|
122
|
+
curateWorkersAi: options.curateWorkersAi !== false,
|
|
123
|
+
fetchImpl: options.fetchImpl,
|
|
124
|
+
providerFetchImpl: options.providerFetchImpl,
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
/** @type {Map<string, object>} */
|
|
128
|
+
const byValue = new Map();
|
|
129
|
+
const push = (row) => {
|
|
130
|
+
if (!row?.value || byValue.has(row.value)) return;
|
|
131
|
+
byValue.set(row.value, row);
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
push({
|
|
135
|
+
value: 'none',
|
|
136
|
+
label: 'None — AST/text only ($0 embeddings)',
|
|
137
|
+
hint: 'deterministic · no provider spend',
|
|
138
|
+
provider: 'none',
|
|
139
|
+
source: 'builtin',
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// Credential-scoped OpenAI embedding models from live /v1/models
|
|
143
|
+
for (const row of status.providerModels?.openai || []) {
|
|
144
|
+
const caps = row.capabilities || {};
|
|
145
|
+
const id = row.provider_model_id || '';
|
|
146
|
+
if (caps.embeddings === true || /^text-embedding-/i.test(id)) {
|
|
147
|
+
const dims = defaultDimensions('openai', id);
|
|
148
|
+
push({
|
|
149
|
+
value: encodeEmbeddingChoice('openai', id, dims),
|
|
150
|
+
label: `OpenAI · ${id}`,
|
|
151
|
+
hint: `credential · ${dims}d`,
|
|
152
|
+
provider: 'openai',
|
|
153
|
+
source: 'provider_api',
|
|
154
|
+
model: id,
|
|
155
|
+
dimensions: dims,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Gemini: if key configured, offer models from knowledge adapter + any discovered embed ids
|
|
161
|
+
const geminiCred = resolveProviderCredential('gemini', { env, home: options.home });
|
|
162
|
+
if (geminiCred?.configured) {
|
|
163
|
+
const registry = createProviderRegistry({
|
|
164
|
+
gemini: { apiKey: geminiCred.value || env.GEMINI_API_KEY },
|
|
165
|
+
});
|
|
166
|
+
const caps = registry.get('gemini').capabilities();
|
|
167
|
+
for (const id of caps.models || []) {
|
|
168
|
+
const dims = defaultDimensions('gemini', id);
|
|
169
|
+
push({
|
|
170
|
+
value: encodeEmbeddingChoice('gemini', id, dims),
|
|
171
|
+
label: `Gemini · ${id}`,
|
|
172
|
+
hint: `credential · ${dims}d`,
|
|
173
|
+
provider: 'gemini',
|
|
174
|
+
source: 'provider_credential',
|
|
175
|
+
model: id,
|
|
176
|
+
dimensions: dims,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Cloudflare Workers AI embedding models — required for Vectorize / CF lanes.
|
|
182
|
+
// Uses live account discovery (Text Embeddings). Provider id = workers-ai (knowledge adapter).
|
|
183
|
+
for (const row of status.providerModels?.cloudflare || []) {
|
|
184
|
+
const caps = row.capabilities || {};
|
|
185
|
+
const id = row.provider_model_id || '';
|
|
186
|
+
const task = String(row.metadata?.task || '').toLowerCase();
|
|
187
|
+
const isEmbed = caps.embeddings === true || task === 'text embeddings' || looksLikeEmbedModel(id);
|
|
188
|
+
if (!isEmbed || !id) continue;
|
|
189
|
+
const dims = defaultDimensions('workers-ai', id);
|
|
190
|
+
push({
|
|
191
|
+
value: encodeEmbeddingChoice('workers-ai', id, dims),
|
|
192
|
+
label: `Workers AI · ${id}`,
|
|
193
|
+
hint: `cloudflare · vectorize-ready · ${dims}d`,
|
|
194
|
+
provider: 'workers-ai',
|
|
195
|
+
source: 'provider_api',
|
|
196
|
+
model: id,
|
|
197
|
+
dimensions: dims,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Optional local Ollama — never required; only offered when online.
|
|
202
|
+
/** @type {object[]} */
|
|
203
|
+
const assistModels = [];
|
|
204
|
+
if (status.local?.online) {
|
|
205
|
+
const ollamaConfig = resolveOllamaConfig({}, env);
|
|
206
|
+
for (const row of status.local.models || []) {
|
|
207
|
+
const name = clean(row.name || row.model);
|
|
208
|
+
if (!name) continue;
|
|
209
|
+
const probe = options.skipOllamaProbe
|
|
210
|
+
? { ok: true, capabilities: [] }
|
|
211
|
+
: await probeOllamaModel(name, ollamaConfig, options.fetchImpl || fetch);
|
|
212
|
+
const caps = Array.isArray(probe.capabilities) ? probe.capabilities : [];
|
|
213
|
+
const isEmbed = looksLikeEmbedModel(name) || caps.includes('embedding') || caps.includes('embed');
|
|
214
|
+
if (isEmbed) {
|
|
215
|
+
// Prefer probed dim length when the adapter returns it; else name hint.
|
|
216
|
+
const probedDims = Number(probe.dimensions) || Number(probe.embedding_length) || 0;
|
|
217
|
+
const dims = probedDims > 0 ? probedDims : defaultDimensions('ollama', name);
|
|
218
|
+
push({
|
|
219
|
+
value: encodeEmbeddingChoice('ollama', name, dims),
|
|
220
|
+
label: `Ollama · ${name}`,
|
|
221
|
+
hint: `local optional · ${dims}d`,
|
|
222
|
+
provider: 'ollama',
|
|
223
|
+
source: 'ollama_tags',
|
|
224
|
+
model: name,
|
|
225
|
+
dimensions: dims,
|
|
226
|
+
});
|
|
227
|
+
} else {
|
|
228
|
+
assistModels.push({
|
|
229
|
+
value: `ollama|${name}`,
|
|
230
|
+
label: `Ollama · ${name}`,
|
|
231
|
+
hint: 'local assist (allowlist suggestions)',
|
|
232
|
+
provider: 'ollama',
|
|
233
|
+
model: name,
|
|
234
|
+
source: 'ollama_tags',
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return {
|
|
241
|
+
options: [...byValue.values()],
|
|
242
|
+
inventory: status,
|
|
243
|
+
assistModels,
|
|
244
|
+
ollama: status.local,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Ask a local Ollama chat model to suggest include/exclude paths.
|
|
250
|
+
* Optional — never required for ingest.
|
|
251
|
+
*
|
|
252
|
+
* @param {{ root: string, model: string, topLevel: string[], fetchImpl?: typeof fetch, env?: object }} opts
|
|
253
|
+
*/
|
|
254
|
+
export async function suggestScopeWithLocalModel(opts) {
|
|
255
|
+
const env = opts.env || process.env;
|
|
256
|
+
const config = resolveOllamaConfig({}, env);
|
|
257
|
+
const endpoint = new URL('/api/generate', config.baseUrl);
|
|
258
|
+
const listing = (opts.topLevel || []).slice(0, 80).join('\n');
|
|
259
|
+
const prompt = [
|
|
260
|
+
'You help configure a repository knowledge allowlist/denylist for AgentSam codebaseindex.',
|
|
261
|
+
'Return ONLY compact JSON: {"include":["..."],"exclude":["..."],"rationale":"..."}',
|
|
262
|
+
'include/exclude must be relative path segments (no globs). Prefer source dirs; exclude deps/build caches.',
|
|
263
|
+
'Machine inventory already classified top-level paths — prefer refining those categories, do not invent unrelated roots.',
|
|
264
|
+
`Repository root: ${opts.root}`,
|
|
265
|
+
opts.categories ? `Categories JSON: ${JSON.stringify(opts.categories)}` : '',
|
|
266
|
+
'Top-level entries:',
|
|
267
|
+
listing || '(empty)',
|
|
268
|
+
].filter(Boolean).join('\n');
|
|
269
|
+
|
|
270
|
+
const response = await (opts.fetchImpl || fetch)(endpoint, {
|
|
271
|
+
method: 'POST',
|
|
272
|
+
headers: { 'content-type': 'application/json' },
|
|
273
|
+
body: JSON.stringify({ model: opts.model, prompt, stream: false, format: 'json' }),
|
|
274
|
+
signal: AbortSignal.timeout(60_000),
|
|
275
|
+
});
|
|
276
|
+
if (!response.ok) {
|
|
277
|
+
throw new Error(`ollama_assist_failed:HTTP ${response.status}`);
|
|
278
|
+
}
|
|
279
|
+
const body = await response.json();
|
|
280
|
+
const raw = clean(body?.response);
|
|
281
|
+
let parsed;
|
|
282
|
+
try {
|
|
283
|
+
parsed = JSON.parse(raw);
|
|
284
|
+
} catch {
|
|
285
|
+
throw new Error('ollama_assist_invalid_json');
|
|
286
|
+
}
|
|
287
|
+
const include = Array.isArray(parsed.include) ? parsed.include.map(clean).filter(Boolean) : [];
|
|
288
|
+
const exclude = Array.isArray(parsed.exclude) ? parsed.exclude.map(clean).filter(Boolean) : [];
|
|
289
|
+
return {
|
|
290
|
+
include,
|
|
291
|
+
exclude,
|
|
292
|
+
rationale: clean(parsed.rationale) || null,
|
|
293
|
+
model: opts.model,
|
|
294
|
+
provider: 'ollama',
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export { probeOllama, resolveOllamaConfig, looksLikeEmbedModel, defaultDimensions, WORKERS_AI_EMBED_DIMS };
|